home *** CD-ROM | disk | FTP | other *** search
/ Enter 2001 April / EnterCD4.iso / Update / SQL Server SP3 / sql70sp3i.exe / INSTALL / instdist.sql < prev    next >
Encoding:
Text File  |  2000-09-13  |  602.7 KB  |  16,732 lines

  1. /***********
  2. InstDist.SQL   
  3. ***********/
  4. if (    (db_id()     = 1)  -- 'master' db
  5.     OR
  6.         is_srvrolemember('sysadmin') <> 1  -- SA
  7.    )
  8.     begin
  9.     raiserror('Error, the ''master'' database cannot be the distribution database.  This ISQL run will terminate now.'
  10.                  ,11,127)  -- State=127 should halt ISQL.EXE
  11.     end
  12.  
  13. if (    (db_id()     = 1)  -- 'master' db
  14.     OR
  15.         is_srvrolemember('sysadmin') <> 1 -- SA
  16.    )
  17.     begin
  18.     raiserror('Minor error, because previous attempt to gently terminate ISQL failed.  Harshly killing spid.'
  19.                  ,22,127) with log   -- SeverityLevel>=19 kills spid.
  20.     end
  21. select 'At top, db_name()=',db_name()
  22.  
  23. go
  24.  
  25.  
  26. declare @dbname sysname
  27. select  @dbname = db_name()
  28. execute('dump transaction ' +@dbname+ ' with no_log')
  29. go
  30. checkpoint
  31.  
  32. go
  33. EXEC dbo.sp_configure 'allow updates', 1
  34. GO
  35. reconfigure with override
  36. GO
  37.  
  38. set ANSI_NULLS off
  39. go
  40.  
  41. declare @dbname sysname
  42. select  @dbname = db_name()
  43. exec dbo.sp_dbcmptlevel @dbname, 70
  44. go
  45.  
  46. /****************************************************************************/
  47. PRINT ''
  48. PRINT 'Creating distribution tables'
  49. PRINT ''
  50. /****************************************************************************/
  51. EXEC dbo.sp_MScreate_dist_tables
  52. go
  53.  
  54. declare @dbname sysname
  55. select  @dbname = db_name()
  56. execute('dump transaction ' +@dbname+ ' with no_log')
  57. go
  58.  
  59. exec dbo.sp_MS_upd_sysobj_category 1  --Capture now_datetime for use below.
  60.  
  61. /****************************************************************************/
  62. PRINT ''
  63. PRINT 'Dropping all distribution stored procedures'
  64. PRINT ''
  65. /****************************************************************************/
  66. IF EXISTS (SELECT * FROM sysobjects WHERE
  67.    name = 'sp_MSadd_repl_command' and type = 'P')
  68.       DROP PROCEDURE sp_MSadd_repl_command
  69.  
  70. IF EXISTS (SELECT * FROM sysobjects WHERE
  71.    name = 'sp_MScheckretention' and type = 'P')
  72.       DROP PROCEDURE sp_MScheckretention
  73.  
  74. IF EXISTS (SELECT * FROM sysobjects WHERE
  75.    name = 'sp_MScheck_Jet_Subscriber' and type = 'P')
  76.       DROP PROCEDURE sp_MScheck_Jet_Subscriber
  77.  
  78. IF EXISTS (SELECT * FROM sysobjects WHERE
  79.    name = 'sp_MSadd_repl_commands10' and type = 'P')
  80.       DROP PROCEDURE sp_MSadd_repl_commands10
  81.  
  82. IF EXISTS (SELECT * FROM sysobjects WHERE
  83.    name = 'sp_MSadd_repl_commands27' and type = 'P')
  84.       DROP PROCEDURE sp_MSadd_repl_commands27
  85.  
  86. IF EXISTS (SELECT * FROM sysobjects WHERE
  87.    name = 'sp_MSadd_repl_commands27hp' and type = 'P')
  88.       DROP PROCEDURE sp_MSadd_repl_commands27hp
  89.  
  90. IF EXISTS (SELECT * FROM sysobjects WHERE
  91.    name = 'sp_MSadd_repl_commands27hp6x' and type = 'P')
  92.       DROP PROCEDURE sp_MSadd_repl_commands27hp6x
  93.  
  94. IF EXISTS (SELECT * FROM sysobjects WHERE
  95.    name = 'sp_MSadd_subscription' and type = 'P')
  96.       DROP PROCEDURE sp_MSadd_subscription
  97.  
  98. IF EXISTS (SELECT * FROM sysobjects WHERE                    
  99.    name = 'sp_MSdrop_subscription' and type = 'P')
  100.       DROP PROCEDURE sp_MSdrop_subscription
  101.  
  102. IF EXISTS (SELECT * FROM sysobjects WHERE   
  103.     name = 'sp_MSupdate_subscription' and type = 'P')
  104.        DROP PROCEDURE sp_MSupdate_subscription
  105.  
  106. IF EXISTS (SELECT * FROM sysobjects WHERE
  107.     name = 'sp_MSget_repl_commands' and type = 'P')
  108.        DROP PROCEDURE sp_MSget_repl_commands
  109.  
  110. IF EXISTS (SELECT * FROM sysobjects WHERE
  111.     name = 'sp_MSget_repl_cmds_anonymous' and type = 'P')
  112.        DROP PROCEDURE sp_MSget_repl_cmds_anonymous
  113.  
  114. IF EXISTS (select * from sysobjects where
  115.    name = 'sp_MSdrop_agent_entry' and type = 'P')
  116.       DROP PROCEDURE sp_MSdrop_agent_entry
  117.       
  118. IF EXISTS (SELECT * FROM sysobjects WHERE
  119.     name = 'sp_MSadd_anonymous_agent' and type = 'P')
  120.        DROP PROCEDURE sp_MSadd_anonymous_agent
  121.  
  122. -- SyncTran
  123. IF EXISTS (SELECT * FROM sysobjects WHERE
  124.     name = 'sp_MSget_repl_cmds_loopback' and type = 'P')
  125.        DROP PROCEDURE sp_MSget_repl_cmds_loopback
  126.  
  127. IF EXISTS (SELECT * FROM sysobjects WHERE
  128.     name = 'sp_MSget_undelivered_commands' and type = 'P')
  129.        DROP PROCEDURE sp_MSget_undelivered_commands
  130.  
  131. IF EXISTS (SELECT * FROM sysobjects WHERE
  132.     name = 'sp_MSget_anonymous_cmds' and type = 'P')
  133.        DROP PROCEDURE sp_MSget_anonymous_cmds
  134.  
  135. IF EXISTS (SELECT * FROM sysobjects WHERE
  136.     name = 'sp_MSget_loopback_cmds' and type = 'P')
  137.        DROP PROCEDURE sp_MSget_loopback_cmds
  138.  
  139. IF EXISTS (SELECT * FROM sysobjects WHERE
  140.     name = 'sp_MSanonymous_status' and type = 'P')
  141.        DROP PROCEDURE sp_MSanonymous_status
  142.  
  143. IF EXISTS (SELECT * FROM sysobjects WHERE
  144.     name = 'sp_MSsubscription_status' and type = 'P')
  145.        DROP PROCEDURE sp_MSsubscription_status
  146. GO    
  147.  
  148. declare @dbname sysname
  149. select  @dbname = db_name()
  150. execute('dump transaction ' +@dbname+ ' with no_log')
  151.  
  152. go
  153.  
  154. IF EXISTS (SELECT * FROM sysobjects WHERE
  155.    name = 'sp_MSget_last_transaction' and type = 'P')
  156.       DROP PROCEDURE sp_MSget_last_transaction
  157.     
  158.  
  159. IF EXISTS (SELECT * FROM sysobjects WHERE
  160.    name = 'sp_MSadd_subscriber_info' and type = 'P')
  161.       DROP PROCEDURE sp_MSadd_subscriber_info
  162.  
  163. IF EXISTS (SELECT * FROM sysobjects WHERE
  164.    name = 'sp_MSadd_subscriber_schedule' and type = 'P')
  165.       DROP PROCEDURE sp_MSadd_subscriber_schedule
  166.  
  167. IF EXISTS (SELECT * FROM sysobjects WHERE
  168.    name = 'sp_MSupdate_subscriber_info' and type = 'P')
  169.       DROP PROCEDURE sp_MSupdate_subscriber_info
  170.  
  171. IF EXISTS (SELECT * FROM sysobjects WHERE
  172.    name = 'sp_MSupdate_subscriber_schedule' and type = 'P')
  173.       DROP PROCEDURE sp_MSupdate_subscriber_schedule
  174.  
  175. IF EXISTS (SELECT * FROM sysobjects WHERE
  176.    name = 'sp_MSdrop_subscriber_info' and type = 'P')
  177.       DROP PROCEDURE sp_MSdrop_subscriber_info
  178.  
  179. IF EXISTS (SELECT * FROM sysobjects WHERE
  180.    name = 'sp_MShelp_subscriber_info' and type = 'P')
  181.       DROP PROCEDURE sp_MShelp_subscriber_info
  182.  
  183. IF EXISTS (select * from sysobjects where
  184.    name = 'sp_MSdistribution_counters' and type = 'P')
  185.       DROP PROCEDURE sp_MSdistribution_counters
  186.  
  187. IF EXISTS (select * from sysobjects where
  188.    name = 'sp_MSremove_published_jobs' and type = 'P')
  189.       DROP PROCEDURE sp_MSremove_published_jobs
  190.  
  191. IF EXISTS (select * from sysobjects where
  192.    name = 'sp_MSset_snapshot_xact_seqno' and type = 'P')
  193.       DROP PROCEDURE sp_MSset_snapshot_xact_seqno
  194.  
  195. IF EXISTS (select * from sysobjects where
  196.    name = 'sp_MSadd_snapshot_history' and type = 'P')
  197.       DROP PROCEDURE sp_MSadd_snapshot_history
  198.  
  199. IF EXISTS (select * from sysobjects where
  200.    name = 'sp_MSadd_logreader_history' and type = 'P')
  201.       DROP PROCEDURE sp_MSadd_logreader_history
  202.  
  203. IF EXISTS (select * from sysobjects where
  204.    name = 'sp_MSadd_distribution_history' and type = 'P')
  205.       DROP PROCEDURE sp_MSadd_distribution_history
  206.  
  207. IF EXISTS (select * from sysobjects where
  208.    name = 'sp_MSdistribution_cleanup' and type = 'P')
  209.       DROP PROCEDURE sp_MSdistribution_cleanup
  210.  
  211. IF EXISTS (select * from sysobjects where
  212.    name = 'sp_MSsubscription_cleanup' and type = 'P')
  213.       DROP PROCEDURE sp_MSsubscription_cleanup
  214.  
  215. IF EXISTS (select * from sysobjects where
  216.    name = 'sp_MSdistribution_delete' and type = 'P')
  217.       DROP PROCEDURE sp_MSdistribution_delete
  218.  
  219. IF EXISTS (select * from sysobjects where
  220.    name = 'sp_MSmaximum_cleanup_seqno' and type = 'P')
  221.       DROP PROCEDURE sp_MSmaximum_cleanup_seqno
  222.  
  223. IF EXISTS (select * from sysobjects where
  224.    name = 'sp_MSdrop_snapshot_dirs' and type = 'P')
  225.       DROP PROCEDURE sp_MSdrop_snapshot_dirs
  226.  
  227. IF EXISTS (select * from sysobjects where
  228.    name = 'sp_MSfast_delete_trans' and type = 'P')
  229.       DROP PROCEDURE sp_MSfast_delete_trans
  230.  
  231. IF EXISTS (select * from sysobjects where
  232.    name = 'sp_MSdelete_publisherdb_trans' and type = 'P')
  233.       DROP PROCEDURE sp_MSdelete_publisherdb_trans
  234.  
  235. IF EXISTS (select * from sysobjects where
  236.    name = 'sp_MShistory_cleanup' and type = 'P')
  237.       DROP PROCEDURE sp_MShistory_cleanup
  238.  
  239. IF EXISTS (select * from sysobjects where
  240.    name = 'sp_MSget_repl_version' and type = 'P')
  241.       DROP PROCEDURE sp_MSget_repl_version
  242.  
  243. IF EXISTS (select * from sysobjects where
  244.    name = 'sp_MSenum_subscriptions' and type = 'P')
  245.       DROP PROCEDURE sp_MSenum_subscriptions
  246.  
  247. IF EXISTS (select * from sysobjects where
  248.    name = 'sp_MSenum_snapshot' and type = 'P')
  249.       DROP PROCEDURE sp_MSenum_snapshot
  250.       
  251. IF EXISTS (select * from sysobjects where
  252.    name = 'sp_MSadd_merge_anonymous_agent' and type = 'P')
  253.       DROP PROCEDURE sp_MSadd_merge_anonymous_agent
  254.     
  255. IF EXISTS (select * from sysobjects where
  256.    name = 'sp_MSenum_snapshot_s' and type = 'P')
  257.       DROP PROCEDURE sp_MSenum_snapshot_s
  258.  
  259. IF EXISTS (select * from sysobjects where
  260.    name = 'sp_MSenum_snapshot_sd' and type = 'P')
  261.       DROP PROCEDURE sp_MSenum_snapshot_sd
  262.  
  263. IF EXISTS (select * from sysobjects where
  264.    name = 'sp_MSenum_logreader' and type = 'P')
  265.       DROP PROCEDURE sp_MSenum_logreader
  266.  
  267. IF EXISTS (select * from sysobjects where
  268.    name = 'sp_MSenum_logreader_s' and type = 'P')
  269.       DROP PROCEDURE sp_MSenum_logreader_s
  270.  
  271. IF EXISTS (select * from sysobjects where
  272.    name = 'sp_MSenum_logreader_sd' and type = 'P')
  273.       DROP PROCEDURE sp_MSenum_logreader_sd
  274.  
  275. IF EXISTS (select * from sysobjects where
  276.    name = 'sp_MSenum_distribution' and type = 'P')
  277.       DROP PROCEDURE sp_MSenum_distribution
  278.  
  279. IF EXISTS (select * from sysobjects where
  280.    name = 'sp_MSenum_distribution_s' and type = 'P')
  281.       DROP PROCEDURE sp_MSenum_distribution_s
  282.  
  283. IF EXISTS (SELECT * FROM sysobjects WHERE
  284.    name = 'sp_MShelp_subscription_status' and type = 'P')
  285.       DROP PROCEDURE sp_MShelp_subscription_status
  286.  
  287. IF EXISTS (SELECT * FROM sysobjects WHERE
  288.    name = 'sp_MScleanup_agent_entry' and type = 'P')
  289.       DROP PROCEDURE sp_MScleanup_agent_entry
  290.  
  291. IF EXISTS (select * from sysobjects where
  292.    name = 'sp_MSenum_distribution_sd' and type = 'P')
  293.       DROP PROCEDURE sp_MSenum_distribution_sd
  294.  
  295. IF EXISTS (select * from sysobjects where
  296.    name = 'sp_MSenum_merge' and type = 'P')
  297.       DROP PROCEDURE sp_MSenum_merge
  298.  
  299. IF EXISTS (select * from sysobjects where
  300.    name = 'sp_MSenum_merge_s' and type = 'P')
  301.       DROP PROCEDURE sp_MSenum_merge_s
  302.  
  303. IF EXISTS (select * from sysobjects where
  304.    name = 'sp_MSenum_merge_sd' and type = 'P')
  305.       DROP PROCEDURE sp_MSenum_merge_sd
  306.  
  307. IF EXISTS (select * from sysobjects where
  308.    name = 'sp_MSadd_repl_error' and type = 'P')
  309.       DROP PROCEDURE sp_MSadd_repl_error
  310.  
  311. IF EXISTS (select * from sysobjects where
  312.    name = 'sp_MSadd_repl_alert' and type = 'P')
  313.       DROP PROCEDURE sp_MSadd_repl_alert
  314.  
  315. IF EXISTS (select * from sysobjects where
  316.    name = 'sp_MSadd_replmergealert' and type = 'P')
  317.       DROP PROCEDURE sp_MSadd_replmergealert
  318.  
  319. IF EXISTS (select * from sysobjects where
  320.    name = 'sp_MSget_new_errorid' and type = 'P')
  321.       DROP PROCEDURE sp_MSget_new_errorid
  322.  
  323. IF EXISTS (select * from sysobjects where
  324.    name = 'sp_MSget_repl_error' and type = 'P')
  325.       DROP PROCEDURE sp_MSget_repl_error
  326.  
  327. IF EXISTS (select * from sysobjects where
  328.    name = 'sp_MSadd_merge_history' and type = 'P')
  329.       DROP PROCEDURE sp_MSadd_merge_history
  330.  
  331. IF EXISTS (select * from sysobjects where
  332.    name = 'sp_MSdist_activate_auto_sub' and type = 'P')
  333.       DROP PROCEDURE sp_MSdist_activate_auto_sub
  334.  
  335. IF EXISTS (select * from sysobjects where
  336.    name = 'sp_MSlock_auto_sub' and type = 'P')
  337.       DROP PROCEDURE sp_MSlock_auto_sub
  338.  
  339. IF EXISTS (select * from sysobjects where
  340.    name = 'sp_MSget_new_xact_seqno' and type = 'P')
  341.       DROP PROCEDURE sp_MSget_new_xact_seqno
  342.  
  343. IF EXISTS (select * from sysobjects where
  344.    name = 'sp_MSvalidate_distpublisher' and type = 'P')
  345.       DROP PROCEDURE sp_MSvalidate_distpublisher
  346.  
  347. IF EXISTS (select * from sysobjects where
  348.    name = 'sp_MSadd_publication' and type = 'P')
  349.       DROP PROCEDURE sp_MSadd_publication
  350.  
  351. IF EXISTS (select * from sysobjects where
  352.    name = 'sp_MSchange_publication' and type = 'P')
  353.       DROP PROCEDURE sp_MSchange_publication
  354.  
  355. IF EXISTS (select * from sysobjects where
  356.    name = 'sp_MSadd_article' and type = 'P')
  357.       DROP PROCEDURE sp_MSadd_article
  358.  
  359. IF EXISTS (select * from sysobjects where
  360.    name = 'sp_MSchange_article' and type = 'P')
  361.       DROP PROCEDURE sp_MSchange_article
  362.  
  363. IF EXISTS (select * from sysobjects where
  364.    name = 'sp_MSdrop_publication' and type = 'P')
  365.       DROP PROCEDURE sp_MSdrop_publication
  366.  
  367. IF EXISTS (select * from sysobjects where
  368.    name = 'sp_MSdrop_article' and type = 'P')
  369.       DROP PROCEDURE sp_MSdrop_article
  370.  
  371. IF EXISTS (select * from sysobjects where
  372.    name = 'sp_MShelp_publication' and type = 'P')
  373.       DROP PROCEDURE sp_MShelp_publication
  374.  
  375. IF EXISTS (select * from sysobjects where
  376.    name = 'sp_MShelp_article' and type = 'P')
  377.       DROP PROCEDURE sp_MShelp_article
  378.  
  379. IF EXISTS (select * from sysobjects where
  380.    name = 'sp_MShelp_subscription' and type = 'P')
  381.       DROP PROCEDURE sp_MShelp_subscription
  382.  
  383. IF EXISTS (select * from sysobjects where
  384.    name = 'sp_MSadd_subscription_3rd' and type = 'P')
  385.       DROP PROCEDURE sp_MSadd_subscription_3rd
  386.  
  387. IF EXISTS (select * from sysobjects where
  388.    name = 'sp_MSdrop_subscription_3rd' and type = 'P')
  389.       DROP PROCEDURE sp_MSdrop_subscription_3rd
  390.  
  391. IF EXISTS (select * from sysobjects where
  392.    name = 'sp_MSactivate_subscriptions' and type = 'P')
  393.       DROP PROCEDURE sp_MSactivate_subscriptions
  394.  
  395. IF EXISTS (select * from sysobjects where
  396.    name = 'sp_MSrepl_raiserror' and type = 'P')
  397.       DROP PROCEDURE sp_MSrepl_raiserror
  398.  
  399. IF EXISTS (select * from sysobjects where
  400.    name = 'sp_MSadd_merge_subscription' and type = 'P')
  401.       DROP PROCEDURE sp_MSadd_merge_subscription
  402.  
  403. IF EXISTS (select * from sysobjects where
  404.    name = 'sp_MSdrop_merge_subscription' and type = 'P')
  405.       DROP PROCEDURE sp_MSdrop_merge_subscription
  406.  
  407. IF EXISTS (select * from sysobjects where
  408.    name = 'sp_MSenum_merge_subscriptions' and type = 'P')
  409.       DROP PROCEDURE sp_MSenum_merge_subscriptions
  410.  
  411. IF EXISTS (select * from sysobjects where
  412.    name = 'sp_MSadd_snapshot_agent' and type = 'P')
  413.       DROP PROCEDURE sp_MSadd_snapshot_agent
  414.  
  415. IF EXISTS (select * from sysobjects where
  416.    name = 'sp_MSdrop_snapshot_agent' and type = 'P')
  417.       DROP PROCEDURE sp_MSdrop_snapshot_agent
  418.  
  419. IF EXISTS (select * from sysobjects where
  420.    name = 'sp_MSadd_logreader_agent' and type = 'P')
  421.       DROP PROCEDURE sp_MSadd_logreader_agent
  422.  
  423. IF EXISTS (select * from sysobjects where
  424.    name = 'sp_MSdrop_logreader_agent' and type = 'P')
  425.       DROP PROCEDURE sp_MSdrop_logreader_agent
  426.  
  427. IF EXISTS (select * from sysobjects where
  428.    name = 'sp_MSadd_distribution_agent' and type = 'P')
  429.       DROP PROCEDURE sp_MSadd_distribution_agent
  430.  
  431. IF EXISTS (select * from sysobjects where
  432.    name = 'sp_MSdrop_distribution_agent' and type = 'P')
  433.       DROP PROCEDURE sp_MSdrop_distribution_agent
  434.  
  435. IF EXISTS (select * from sysobjects where
  436.    name = 'sp_MSdrop_distribution_agentid' and type = 'P')
  437.       DROP PROCEDURE sp_MSdrop_distribution_agentid
  438.  
  439. IF EXISTS (select * from sysobjects where
  440.    name = 'sp_MSdrop_merge_agentid' and type = 'P')
  441.       DROP PROCEDURE sp_MSdrop_merge_agentid
  442.  
  443. IF EXISTS (select * from sysobjects where
  444.    name = 'sp_MSadd_merge_agent' and type = 'P')
  445.       DROP PROCEDURE sp_MSadd_merge_agent
  446.  
  447. IF EXISTS (select * from sysobjects where
  448.    name = 'sp_MSdrop_merge_agent' and type = 'P')
  449.       DROP PROCEDURE sp_MSdrop_merge_agent
  450.  
  451. IF EXISTS (select name from sysobjects where 
  452.    name = 'sp_update_agent_profile' and type = 'P')
  453.     DROP PROCEDURE sp_update_agent_profile
  454.  
  455. IF EXISTS (select name from sysobjects where 
  456.    name = 'sp_MSprofile_in_use' and type = 'P')
  457.     DROP PROCEDURE sp_MSprofile_in_use
  458.  
  459. IF EXISTS (select * from sysobjects where
  460.    name = 'sp_MSreset_subscription' and type = 'P')
  461.       DROP PROCEDURE sp_MSreset_subscription
  462.  
  463. IF EXISTS (select * from sysobjects where
  464.    name = 'sp_MSget_subscription_guid' and type = 'P')
  465.       DROP PROCEDURE sp_MSget_subscription_guid
  466.  
  467. IF EXISTS (select * from sysobjects where
  468.    name = 'sp_MShelp_profile' and type = 'P')
  469.       DROP PROCEDURE sp_MShelp_profile
  470.  
  471. IF EXISTS (select * from sysobjects where
  472.    name = 'sp_MShelp_snapshot_agentid' and type = 'P')
  473.       DROP PROCEDURE sp_MShelp_snapshot_agentid
  474.  
  475. IF EXISTS (select * from sysobjects where
  476.    name = 'sp_MShelp_logreader_agentid' and type = 'P')
  477.       DROP PROCEDURE sp_MShelp_logreader_agentid
  478.  
  479. IF EXISTS (select * from sysobjects where
  480.    name = 'sp_MShelp_merge_agentid' and type = 'P')
  481.       DROP PROCEDURE sp_MShelp_merge_agentid
  482.  
  483. IF EXISTS (select * from sysobjects where
  484.    name = 'sp_MSenum_replication_status' and type = 'P')
  485.       DROP PROCEDURE sp_MSenum_replication_status
  486.  
  487. IF EXISTS (select * from sysobjects where
  488.    name = 'sp_MSagent_stethoscope' and type = 'P')
  489.       DROP PROCEDURE sp_MSagent_stethoscope
  490.  
  491. IF EXISTS (select * from sysobjects where
  492.    name = 'sp_MSlock_distribution_agent' and type = 'P')
  493.       DROP PROCEDURE sp_MSlock_distribution_agent
  494.  
  495. IF EXISTS (select * from sysobjects where
  496.    name = 'sp_MSdetect_nonlogged_shutdown' and type = 'P')
  497.       DROP PROCEDURE sp_MSdetect_nonlogged_shutdown
  498.  
  499. IF EXISTS (select * from sysobjects where
  500.    name = 'sp_MSdistpublisher_cleanup' and type = 'P')
  501.       DROP PROCEDURE sp_MSdistpublisher_cleanup
  502.  
  503. IF EXISTS (select * from sysobjects where
  504.    name = 'sp_MSpublication_access' and type = 'P')
  505.       DROP PROCEDURE sp_MSpublication_access
  506.  
  507. IF EXISTS (select * from sysobjects where
  508.    name = 'sp_MScheck_pull_access' and type = 'P')
  509.       DROP PROCEDURE sp_MScheck_pull_access
  510.  
  511. GO
  512. IF EXISTS (select * from sysobjects where
  513.    name = 'sp_MSdrop_6x_publication' and type = 'P')
  514.       DROP PROCEDURE sp_MSdrop_6x_publication
  515.  
  516. IF EXISTS (select * from sysobjects where
  517.    name = 'sp_MShelp_distribution_agentid' and type = 'P')
  518.       DROP PROCEDURE sp_MShelp_distribution_agentid
  519. GO
  520.  
  521. IF EXISTS (select * from sysobjects where
  522.    name = 'sp_MSreinit_subscription' and type = 'P')
  523.       DROP PROCEDURE sp_MSreinit_subscription
  524. go
  525.  
  526. IF EXISTS (select * from sysobjects where
  527.    name = 'sp_MSmarkreinit' and type = 'P')
  528.       DROP PROCEDURE sp_MSmarkreinit
  529. go
  530.  
  531. IF EXISTS (select * from sysobjects where
  532.    name = 'sp_browsereplcmds' and type = 'P')
  533.       DROP PROCEDURE sp_browsereplcmds
  534. go
  535.  
  536. IF EXISTS (select * from sysobjects where
  537.    name = 'sp_dumpparamcmd' and type = 'P')
  538.       DROP PROCEDURE sp_dumpparamcmd
  539. go
  540.  
  541.  
  542.  
  543. declare @dbname sysname
  544. select  @dbname = db_name()
  545. execute('dump transaction ' +@dbname+ ' with no_log')
  546. go
  547.  
  548. raiserror(15339,-1,-1,'sp_MSadd_repl_command')
  549. go
  550. CREATE PROCEDURE sp_MSadd_repl_command
  551. @publisher_id smallint,
  552. @publisher_db sysname,
  553. @xact_id varbinary(16) = 0x0,
  554. @xact_seqno varbinary(16) = 0x0,
  555. @originator sysname = NULL,
  556. @originator_db sysname = NULL,
  557. @article_id int,
  558. @command_id int,
  559. @type int = 0,
  560. @partial_command bit,
  561. @command varbinary(1024)
  562.  
  563. AS
  564.  
  565.    SET NOCOUNT ON
  566.  
  567.    DECLARE @date datetime
  568.    DECLARE @publisher_database_id int
  569.    declare @originator_id int
  570.  
  571.    SELECT @date = GETDATE()
  572.  
  573.     -- Get publisher database id.
  574.     SELECT @publisher_database_id = id from MSpublisher_databases where publisher_id = @publisher_id and 
  575.         publisher_db = @publisher_db
  576.     
  577.    /* 
  578.    ** To minimize contention, snapshot does not include this SP call
  579.    ** inside a transaction. We have to insert to MSrepl_transactions table
  580.    ** first to ensure clean up stored precedures to work, which only use 
  581.    ** MSrepl_transactions table but NOT MSrepl_commands table to find transactions
  582.    ** to be deleted.
  583.    */
  584.  
  585.    IF @command_id = 1
  586.    BEGIN
  587.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  588.          @xact_id,  @xact_seqno, @date)
  589.       IF @@ERROR <> 0
  590.          RETURN 1
  591.    END
  592.  
  593.    IF @command IS NOT NULL
  594.    begin
  595.       if @originator <> N'' and @originator_db <> N'' and @originator is not null and @originator_db is not null 
  596.       begin
  597.         set @originator_id = null select @originator_id = id from MSrepl_originators where
  598.             publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@originator) and
  599.             dbname = @originator_db
  600.         if @originator_id is null
  601.         begin
  602.             insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  603.                 (@publisher_database_id, @originator, @originator_db)
  604.             select @originator_id = @@identity
  605.         end
  606.       end
  607.       else
  608.         select @originator_id = 0
  609.       
  610.       INSERT INTO MSrepl_commands VALUES (@publisher_database_id, @xact_seqno,
  611.         @type, @article_id, @originator_id, @command_id, @partial_command, @command)
  612.     end
  613.  
  614.     IF @@ERROR <> 0
  615.       RETURN (1)
  616.  
  617. GO  
  618.  
  619. raiserror(15339,-1,-1,'sp_MSadd_repl_commands10')
  620. GO
  621. CREATE PROCEDURE sp_MSadd_repl_commands10
  622. @publisher_id smallint,
  623. @publisher_db sysname,
  624. @xact_id varbinary(16) = 0x0,
  625. @xact_seqno varbinary(16) = 0x0,
  626. @originator sysname,
  627. @originator_db sysname,
  628. @article_id int,
  629. @command_id int,
  630. @type int = 0,
  631. @partial_command bit,
  632. @command varbinary(1024),
  633.  
  634. @1xact_id varbinary(16) = 0x0,
  635.  
  636. @1xact_seqno varbinary(16) = 0x0,
  637. @1originator sysname = NULL,
  638. @1originator_db sysname = NULL,
  639. @1article_id int = 0,
  640. @1command_id int = 0,
  641. @1type int = 0,
  642. @1partial_command bit = 0,
  643. @1command varbinary(1024) = NULL,
  644.  
  645. @2xact_id varbinary(16) = 0x0,
  646.  
  647. @2xact_seqno varbinary(16) = 0x0,
  648. @2originator sysname = NULL,
  649. @2originator_db sysname = NULL,
  650. @2article_id int = 0,
  651. @2command_id int = 0,
  652. @2type int = 0,
  653. @2partial_command bit = 0,
  654. @2command varbinary(1024) = NULL,
  655.  
  656. @3xact_id varbinary(16) = 0x0,
  657.  
  658. @3xact_seqno varbinary(16) = 0x0,
  659. @3originator sysname = NULL,
  660. @3originator_db sysname = NULL,
  661. @3article_id int = 0,
  662. @3command_id int = 0,
  663. @3type int = 0,
  664. @3partial_command bit = 0,
  665. @3command varbinary(1024) = NULL,
  666.  
  667. @4xact_id varbinary(16) = 0x0,
  668.  
  669. @4xact_seqno varbinary(16) = 0x0,
  670. @4originator sysname = NULL,
  671. @4originator_db sysname = NULL,
  672. @4article_id int = 0,
  673. @4command_id int = 0,
  674. @4type int = 0,
  675. @4partial_command bit = 0,
  676. @4command varbinary(1024) = NULL,
  677.  
  678. @5xact_id varbinary(16) = 0x0,
  679.  
  680. @5xact_seqno varbinary(16) = 0x0,
  681. @5originator sysname = NULL,
  682. @5originator_db sysname = NULL,
  683. @5article_id int = 0,
  684. @5command_id int = 0,
  685. @5type int = 0,
  686. @5partial_command bit = 0,
  687. @5command varbinary(1024) = NULL,
  688.  
  689. @6xact_id varbinary(16) = 0x0,
  690.  
  691. @6xact_seqno varbinary(16) = 0x0,
  692. @6originator sysname = NULL,
  693. @6originator_db sysname = NULL,
  694. @6article_id int = 0,
  695. @6command_id int = 0,
  696. @6type int = 0,
  697. @6partial_command bit = 0,
  698. @6command varbinary(1024) = NULL,
  699.  
  700. @7xact_id varbinary(16) = 0x0,
  701.  
  702. @7xact_seqno varbinary(16) = 0x0,
  703. @7originator sysname = NULL,
  704. @7originator_db sysname = NULL,
  705. @7article_id int = 0,
  706. @7command_id int = 0,
  707. @7type int = 0,
  708. @7partial_command bit = 0,
  709. @7command varbinary(1024) = NULL,
  710.  
  711. @8xact_id varbinary(16) = 0x0,
  712.  
  713. @8xact_seqno varbinary(16) = 0x0,
  714. @8originator sysname = NULL,
  715. @8originator_db sysname = NULL,
  716. @8article_id int = 0,
  717. @8command_id int = 0,
  718. @8type int = 0,
  719. @8partial_command bit = 0,
  720. @8command varbinary(1024) = NULL,
  721.  
  722. @9xact_id varbinary(16) = 0x0,
  723.  
  724. @9xact_seqno varbinary(16) = 0x0,
  725. @9originator sysname = NULL,
  726. @9originator_db sysname = NULL,
  727. @9article_id int = 0,
  728. @9command_id int = 0,
  729. @9type int = 0,
  730. @9partial_command bit = 0,
  731. @9command varbinary(1024) = NULL
  732.  
  733. AS
  734.     SET NOCOUNT ON
  735.  
  736.     DECLARE @publisher_database_id int
  737.     DECLARE @date datetime
  738.     declare @originator_id int
  739.  
  740.     SELECT @date = GETDATE()
  741.  
  742.     -- Get publisher database id.
  743.     SELECT @publisher_database_id = id from MSpublisher_databases where publisher_id = @publisher_id and 
  744.         publisher_db = @publisher_db
  745.     
  746.     -- First insert into MS_repl_transactions
  747.     IF @xact_id = 0x0
  748.       goto INSERT_CMDS
  749.     IF @command_id = 1
  750.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  751.          @xact_id,  @xact_seqno, @date)
  752.  
  753.     IF @1xact_id = 0x0
  754.       goto INSERT_CMDS
  755.     IF @1command_id = 1
  756.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  757.          @1xact_id,  @1xact_seqno, @date)
  758.  
  759.     IF @2xact_id = 0x0
  760.       goto INSERT_CMDS
  761.     IF @2command_id = 1
  762.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  763.          @2xact_id,  @2xact_seqno, @date)
  764.     
  765.     IF @3xact_id = 0x0
  766.       goto INSERT_CMDS
  767.     IF @3command_id = 1
  768.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  769.          @3xact_id,  @3xact_seqno, @date)
  770.  
  771.     IF @4xact_id = 0x0
  772.       goto INSERT_CMDS
  773.     IF @4command_id = 1
  774.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  775.         @4xact_id,  @4xact_seqno, @date)
  776.  
  777.     IF @5xact_id = 0x0
  778.       goto INSERT_CMDS
  779.  
  780.     IF @5command_id = 1
  781.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  782.          @5xact_id,  @5xact_seqno, @date)
  783.  
  784.     IF @6xact_id = 0x0
  785.       goto INSERT_CMDS
  786.     IF @6command_id = 1
  787.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  788.          @6xact_id,  @6xact_seqno, @date)
  789.  
  790.     IF @7xact_id = 0x0
  791.       goto INSERT_CMDS
  792.     IF @7command_id = 1
  793.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  794.          @7xact_id,  @7xact_seqno, @date)
  795.  
  796.     IF @8xact_id = 0x0
  797.       goto INSERT_CMDS
  798.     IF @8command_id = 1
  799.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  800.          @8xact_id,  @8xact_seqno, @date)
  801.  
  802.     IF @9xact_id = 0x0
  803.       goto INSERT_CMDS
  804.     IF @9command_id = 1
  805.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  806.          @9xact_id,  @9xact_seqno, @date)
  807.  
  808. INSERT_CMDS:
  809.  
  810.     -- Get the originator_id for the first command 
  811.     if @originator <> N'' and @originator_db <> N'' and @originator is not null and @originator_db is not null 
  812.     begin 
  813.         set @originator_id = null select @originator_id = id from MSrepl_originators where
  814.             publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@originator) and
  815.             dbname = @originator_db
  816.         if @originator_id is null
  817.         begin
  818.             insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  819.                 (@publisher_database_id, @originator, @originator_db)
  820.             select @originator_id = @@identity
  821.         end
  822.     end
  823.     else
  824.         select @originator_id = 0
  825.  
  826.     -- Now insert into MSrepl_commands
  827.     IF @command IS NOT NULL
  828.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  829.             @xact_seqno,@type, @article_id, 
  830.             @originator_id, 
  831.             @command_id, @partial_command, @command)
  832.  
  833.     IF @1xact_id = 0x0
  834.       return
  835.  
  836.     IF @1command IS NOT NULL
  837.     begin
  838.             if @1originator <> N'' and @1originator_db <> N'' and @1originator is not null and @1originator_db is not null 
  839.             begin 
  840.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  841.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@1originator) and
  842.                     dbname = @1originator_db
  843.                 if @originator_id is null
  844.                 begin
  845.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  846.                         (@publisher_database_id, @1originator, @1originator_db)
  847.                     select @originator_id = @@identity
  848.                 end
  849.             end
  850.             else
  851.                 select @originator_id = 0
  852.     
  853.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  854.             @1xact_seqno,@1type, @1article_id, 
  855.             @originator_id, 
  856.             @1command_id, @1partial_command, @1command)
  857.     end
  858.  
  859.     IF @2xact_id = 0x0
  860.       return
  861.  
  862.     IF @2command IS NOT NULL
  863.     begin
  864.             if @2originator <> N'' and @2originator_db <> N'' and @2originator is not null and @2originator_db is not null 
  865.             begin 
  866.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  867.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@2originator) and
  868.                     dbname = @2originator_db
  869.                 if @originator_id is null
  870.                 begin
  871.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  872.                         (@publisher_database_id, @2originator, @2originator_db)
  873.                     select @originator_id = @@identity
  874.                 end
  875.             end
  876.             else
  877.                 select @originator_id = 0
  878.     
  879.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  880.             @2xact_seqno,@2type, @2article_id, 
  881.             @originator_id, 
  882.             @2command_id, @2partial_command, @2command)
  883.     end
  884.  
  885.     IF @3xact_id = 0x0
  886.       return
  887.     IF @3command IS NOT NULL
  888.     begin
  889.             if @3originator <> N'' and @3originator_db <> N'' and @3originator is not null and @3originator_db is not null 
  890.             begin 
  891.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  892.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@3originator) and
  893.                     dbname = @3originator_db
  894.                 if @originator_id is null
  895.                 begin
  896.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  897.                         (@publisher_database_id, @3originator, @3originator_db)
  898.                     select @originator_id = @@identity
  899.                 end
  900.             end
  901.             else
  902.                 select @originator_id = 0
  903.     
  904.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  905.             @3xact_seqno,@3type, @3article_id, 
  906.             @originator_id, 
  907.             @3command_id, @3partial_command, @3command)
  908.     end
  909.  
  910.     IF @4xact_id = 0x0
  911.       return
  912.     IF @4command IS NOT NULL
  913.     begin
  914.             if @4originator <> N'' and @4originator_db <> N'' and @4originator is not null and @4originator_db is not null 
  915.             begin 
  916.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  917.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@4originator) and
  918.                     dbname = @4originator_db
  919.                 if @originator_id is null
  920.                 begin
  921.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  922.                         (@publisher_database_id, @4originator, @4originator_db)
  923.                     select @originator_id = @@identity
  924.                 end
  925.             end
  926.             else
  927.                 select @originator_id = 0
  928.     
  929.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  930.             @4xact_seqno,@4type, @4article_id, 
  931.             @originator_id, 
  932.             @4command_id, @4partial_command, @4command)
  933.     end
  934.  
  935.     IF @5xact_id = 0x0
  936.       return
  937.     IF @5command IS NOT NULL
  938.     begin
  939.             if @5originator <> N'' and @5originator_db <> N'' and @5originator is not null and @5originator_db is not null 
  940.             begin 
  941.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  942.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@5originator) and
  943.                     dbname = @5originator_db
  944.                 if @originator_id is null
  945.                 begin
  946.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  947.                         (@publisher_database_id, @5originator, @5originator_db)
  948.                     select @originator_id = @@identity
  949.                 end
  950.             end
  951.             else
  952.                 select @originator_id = 0
  953.     
  954.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  955.             @5xact_seqno,@5type, @5article_id, 
  956.             @originator_id, 
  957.             @5command_id, @5partial_command, @5command)
  958.     end
  959.  
  960.     IF @6xact_id = 0x0
  961.       return
  962.     IF @6command IS NOT NULL
  963.     begin
  964.             if @6originator <> N'' and @6originator_db <> N'' and @6originator is not null and @6originator_db is not null 
  965.             begin 
  966.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  967.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@6originator) and
  968.                     dbname = @6originator_db
  969.                 if @originator_id is null
  970.                 begin
  971.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  972.                         (@publisher_database_id, @6originator, @6originator_db)
  973.                     select @originator_id = @@identity
  974.                 end
  975.             end
  976.             else
  977.                 select @originator_id = 0
  978.     
  979.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  980.             @6xact_seqno,@6type, @6article_id, 
  981.             @originator_id, 
  982.             @6command_id, @6partial_command, @6command)
  983.     end
  984.  
  985.     IF @7xact_id = 0x0
  986.       return
  987.     IF @7command IS NOT NULL
  988.     begin
  989.             if @7originator <> N'' and @7originator_db <> N'' and @7originator is not null and @7originator_db is not null 
  990.             begin 
  991.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  992.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@7originator) and
  993.                     dbname = @7originator_db
  994.                 if @originator_id is null
  995.                 begin
  996.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  997.                         (@publisher_database_id, @7originator, @7originator_db)
  998.                     select @originator_id = @@identity
  999.                 end
  1000.             end
  1001.             else
  1002.                 select @originator_id = 0
  1003.     
  1004.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1005.             @7xact_seqno,@7type, @7article_id, 
  1006.             @originator_id, 
  1007.             @7command_id, @7partial_command, @7command)
  1008.     end
  1009.  
  1010.     IF @8xact_id = 0x0
  1011.       return
  1012.     IF @8command IS NOT NULL
  1013.     begin
  1014.             if @8originator <> N'' and @8originator_db <> N'' and @8originator is not null and @8originator_db is not null 
  1015.             begin 
  1016.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1017.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@8originator) and
  1018.                     dbname = @8originator_db
  1019.                 if @originator_id is null
  1020.                 begin
  1021.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1022.                         (@publisher_database_id, @8originator, @8originator_db)
  1023.                     select @originator_id = @@identity
  1024.                 end
  1025.             end
  1026.             else
  1027.                 select @originator_id = 0
  1028.     
  1029.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1030.             @8xact_seqno,@8type, @8article_id, 
  1031.             @originator_id, 
  1032.             @8command_id, @8partial_command, @8command)
  1033.     end
  1034.  
  1035.     IF @9xact_id = 0x0
  1036.       return
  1037.     IF @9command IS NOT NULL
  1038.     begin
  1039.             if @9originator <> N'' and @9originator_db <> N'' and @9originator is not null and @9originator_db is not null 
  1040.             begin 
  1041.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1042.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@9originator) and
  1043.                     dbname = @9originator_db
  1044.                 if @originator_id is null
  1045.                 begin
  1046.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1047.                         (@publisher_database_id, @9originator, @9originator_db)
  1048.                     select @originator_id = @@identity
  1049.                 end
  1050.             end
  1051.             else
  1052.                 select @originator_id = 0
  1053.     
  1054.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1055.             @9xact_seqno,@9type, @9article_id, 
  1056.             @originator_id, 
  1057.             @9command_id, @9partial_command, @9command)
  1058.     end
  1059.  
  1060.     IF @@ERROR <> 0
  1061.       return (1)
  1062. GO
  1063.  
  1064. raiserror(15339,-1,-1,'sp_MSadd_repl_commands27')
  1065. GO
  1066. CREATE PROCEDURE sp_MSadd_repl_commands27
  1067. @publisher_id smallint,
  1068. @publisher_db sysname,
  1069. @xact_id varbinary(16) = 0x0,
  1070. @xact_seqno varbinary(16) = 0x0,
  1071. @originator sysname,
  1072. @originator_db sysname,
  1073. @article_id int,
  1074. @command_id int,
  1075. @type int = 0,
  1076. @partial_command bit,
  1077. @command varbinary(1024),
  1078.  
  1079. @1xact_id varbinary(16) = 0x0,
  1080.  
  1081. @1xact_seqno varbinary(16) = 0x0,
  1082. @1originator sysname = NULL,
  1083. @1originator_db sysname = NULL,
  1084. @1article_id int = 0,
  1085. @1command_id int = 0,
  1086. @1type int = 0,
  1087. @1partial_command bit = 0,
  1088. @1command varbinary(1024) = NULL,
  1089.  
  1090. @2xact_id varbinary(16) = 0x0,
  1091.  
  1092. @2xact_seqno varbinary(16) = 0x0,
  1093. @2originator sysname = NULL,
  1094. @2originator_db sysname = NULL,
  1095. @2article_id int = 0,
  1096. @2command_id int = 0,
  1097. @2type int = 0,
  1098. @2partial_command bit = 0,
  1099. @2command varbinary(1024) = NULL,
  1100.  
  1101. @3xact_id varbinary(16) = 0x0,
  1102.  
  1103. @3xact_seqno varbinary(16) = 0x0,
  1104. @3originator sysname = NULL,
  1105. @3originator_db sysname = NULL,
  1106. @3article_id int = 0,
  1107. @3command_id int = 0,
  1108. @3type int = 0,
  1109. @3partial_command bit = 0,
  1110. @3command varbinary(1024) = NULL,
  1111.  
  1112. @4xact_id varbinary(16) = 0x0,
  1113.  
  1114. @4xact_seqno varbinary(16) = 0x0,
  1115. @4originator sysname = NULL,
  1116. @4originator_db sysname = NULL,
  1117. @4article_id int = 0,
  1118. @4command_id int = 0,
  1119. @4type int = 0,
  1120. @4partial_command bit = 0,
  1121. @4command varbinary(1024) = NULL,
  1122.  
  1123. @5xact_id varbinary(16) = 0x0,
  1124.  
  1125. @5xact_seqno varbinary(16) = 0x0,
  1126. @5originator sysname = NULL,
  1127. @5originator_db sysname = NULL,
  1128. @5article_id int = 0,
  1129. @5command_id int = 0,
  1130. @5type int = 0,
  1131. @5partial_command bit = 0,
  1132. @5command varbinary(1024) = NULL,
  1133.  
  1134. @6xact_id varbinary(16) = 0x0,
  1135.  
  1136. @6xact_seqno varbinary(16) = 0x0,
  1137. @6originator sysname = NULL,
  1138. @6originator_db sysname = NULL,
  1139. @6article_id int = 0,
  1140. @6command_id int = 0,
  1141. @6type int = 0,
  1142. @6partial_command bit = 0,
  1143. @6command varbinary(1024) = NULL,
  1144.  
  1145. @7xact_id varbinary(16) = 0x0,
  1146.  
  1147. @7xact_seqno varbinary(16) = 0x0,
  1148. @7originator sysname = NULL,
  1149. @7originator_db sysname = NULL,
  1150. @7article_id int = 0,
  1151. @7command_id int = 0,
  1152. @7type int = 0,
  1153. @7partial_command bit = 0,
  1154. @7command varbinary(1024) = NULL,
  1155.  
  1156. @8xact_id varbinary(16) = 0x0,
  1157.  
  1158. @8xact_seqno varbinary(16) = 0x0,
  1159. @8originator sysname = NULL,
  1160. @8originator_db sysname = NULL,
  1161. @8article_id int = 0,
  1162. @8command_id int = 0,
  1163. @8type int = 0,
  1164. @8partial_command bit = 0,
  1165. @8command varbinary(1024) = NULL,
  1166.  
  1167. @9xact_id varbinary(16) = 0x0,
  1168.  
  1169. @9xact_seqno varbinary(16) = 0x0,
  1170. @9originator sysname = NULL,
  1171. @9originator_db sysname = NULL,
  1172. @9article_id int = 0,
  1173. @9command_id int = 0,
  1174. @9type int = 0,
  1175. @9partial_command bit = 0,
  1176. @9command varbinary(1024) = NULL,
  1177.  
  1178. @10xact_id varbinary(16) = 0x0,
  1179.  
  1180. @10xact_seqno varbinary(16) = 0x0,
  1181. @10originator sysname = NULL,
  1182. @10originator_db sysname = NULL,
  1183. @10article_id int = 0,
  1184. @10command_id int = 0,
  1185. @10type int = 0,
  1186. @10partial_command bit = 0,
  1187. @10command varbinary(1024) = NULL,
  1188.  
  1189. @11xact_id varbinary(16) = 0x0,
  1190.  
  1191. @11xact_seqno varbinary(16) = 0x0,
  1192. @11originator sysname = NULL,
  1193. @11originator_db sysname = NULL,
  1194. @11article_id int = 0,
  1195. @11command_id int = 0,
  1196. @11type int = 0,
  1197. @11partial_command bit = 0,
  1198. @11command varbinary(1024) = NULL,
  1199.  
  1200. @12xact_id varbinary(16) = 0x0,
  1201.  
  1202. @12xact_seqno varbinary(16) = 0x0,
  1203. @12originator sysname = NULL,
  1204. @12originator_db sysname = NULL,
  1205. @12article_id int = 0,
  1206. @12command_id int = 0,
  1207. @12type int = 0,
  1208. @12partial_command bit = 0,
  1209. @12command varbinary(1024) = NULL,
  1210.  
  1211. @13xact_id varbinary(16) = 0x0,
  1212.  
  1213. @13xact_seqno varbinary(16) = 0x0,
  1214. @13originator sysname = NULL,
  1215. @13originator_db sysname = NULL,
  1216. @13article_id int = 0,
  1217. @13command_id int = 0,
  1218. @13type int = 0,
  1219. @13partial_command bit = 0,
  1220. @13command varbinary(1024) = NULL,
  1221.  
  1222. @14xact_id varbinary(16) = 0x0,
  1223.  
  1224. @14xact_seqno varbinary(16) = 0x0,
  1225. @14originator sysname = NULL,
  1226. @14originator_db sysname = NULL,
  1227. @14article_id int = 0,
  1228. @14command_id int = 0,
  1229. @14type int = 0,
  1230. @14partial_command bit = 0,
  1231. @14command varbinary(1024) = NULL,
  1232.  
  1233. @15xact_id varbinary(16) = 0x0,
  1234.  
  1235. @15xact_seqno varbinary(16) = 0x0,
  1236. @15originator sysname = NULL,
  1237. @15originator_db sysname = NULL,
  1238. @15article_id int = 0,
  1239. @15command_id int = 0,
  1240. @15type int = 0,
  1241. @15partial_command bit = 0,
  1242. @15command varbinary(1024) = NULL,
  1243.  
  1244. @16xact_id varbinary(16) = 0x0,
  1245.  
  1246. @16xact_seqno varbinary(16) = 0x0,
  1247. @16originator sysname = NULL,
  1248. @16originator_db sysname = NULL,
  1249. @16article_id int = 0,
  1250. @16command_id int = 0,
  1251. @16type int = 0,
  1252. @16partial_command bit = 0,
  1253. @16command varbinary(1024) = NULL,
  1254.  
  1255. @17xact_id varbinary(16) = 0x0,
  1256.  
  1257. @17xact_seqno varbinary(16) = 0x0,
  1258. @17originator sysname = NULL,
  1259. @17originator_db sysname = NULL,
  1260. @17article_id int = 0,
  1261. @17command_id int = 0,
  1262. @17type int = 0,
  1263. @17partial_command bit = 0,
  1264. @17command varbinary(1024) = NULL,
  1265.  
  1266. @18xact_id varbinary(16) = 0x0,
  1267.  
  1268. @18xact_seqno varbinary(16) = 0x0,
  1269. @18originator sysname = NULL,
  1270. @18originator_db sysname = NULL,
  1271. @18article_id int = 0,
  1272. @18command_id int = 0,
  1273. @18type int = 0,
  1274. @18partial_command bit = 0,
  1275. @18command varbinary(1024) = NULL,
  1276.  
  1277. @19xact_id varbinary(16) = 0x0,
  1278.  
  1279. @19xact_seqno varbinary(16) = 0x0,
  1280. @19originator sysname = NULL,
  1281. @19originator_db sysname = NULL,
  1282. @19article_id int = 0,
  1283. @19command_id int = 0,
  1284. @19type int = 0,
  1285. @19partial_command bit = 0,
  1286. @19command varbinary(1024) = NULL,
  1287.  
  1288. @20xact_id varbinary(16) = 0x0,
  1289.  
  1290. @20xact_seqno varbinary(16) = 0x0,
  1291. @20originator sysname = NULL,
  1292. @20originator_db sysname = NULL,
  1293. @20article_id int = 0,
  1294. @20command_id int = 0,
  1295. @20type int = 0,
  1296. @20partial_command bit = 0,
  1297. @20command varbinary(1024) = NULL,
  1298.  
  1299. @21xact_id varbinary(16) = 0x0,
  1300.  
  1301. @21xact_seqno varbinary(16) = 0x0,
  1302. @21originator sysname = NULL,
  1303. @21originator_db sysname = NULL,
  1304. @21article_id int = 0,
  1305. @21command_id int = 0,
  1306. @21type int = 0,
  1307. @21partial_command bit = 0,
  1308. @21command varbinary(1024) = NULL,
  1309.  
  1310. @22xact_id varbinary(16) = 0x0,
  1311.  
  1312. @22xact_seqno varbinary(16) = 0x0,
  1313. @22originator sysname = NULL,
  1314. @22originator_db sysname = NULL,
  1315. @22article_id int = 0,
  1316. @22command_id int = 0,
  1317. @22type int = 0,
  1318. @22partial_command bit = 0,
  1319. @22command varbinary(1024) = NULL,
  1320.  
  1321. @23xact_id varbinary(16) = 0x0,
  1322.  
  1323. @23xact_seqno varbinary(16) = 0x0,
  1324. @23originator sysname = NULL,
  1325. @23originator_db sysname = NULL,
  1326. @23article_id int = 0,
  1327. @23command_id int = 0,
  1328. @23type int = 0,
  1329. @23partial_command bit = 0,
  1330. @23command varbinary(1024) = NULL,
  1331.  
  1332. @24xact_id varbinary(16) = 0x0,
  1333.  
  1334. @24xact_seqno varbinary(16) = 0x0,
  1335. @24originator sysname = NULL,
  1336. @24originator_db sysname = NULL,
  1337. @24article_id int = 0,
  1338. @24command_id int = 0,
  1339. @24type int = 0,
  1340. @24partial_command bit = 0,
  1341. @24command varbinary(1024) = NULL,
  1342.  
  1343. @25xact_id varbinary(16) = 0x0,
  1344.  
  1345. @25xact_seqno varbinary(16) = 0x0,
  1346. @25originator sysname = NULL,
  1347. @25originator_db sysname = NULL,
  1348. @25article_id int = 0,
  1349. @25command_id int = 0,
  1350. @25type int = 0,
  1351. @25partial_command bit = 0,
  1352. @25command varbinary(1024) = NULL,
  1353.  
  1354. @26xact_id varbinary(16) = 0x0,
  1355.  
  1356. @26xact_seqno varbinary(16) = 0x0,
  1357. @26originator sysname = NULL,
  1358. @26originator_db sysname = NULL,
  1359. @26article_id int = 0,
  1360. @26command_id int = 0,
  1361. @26type int = 0,
  1362. @26partial_command bit = 0,
  1363. @26command varbinary(1024) = NULL
  1364.  
  1365. AS
  1366.  
  1367.     SET NOCOUNT ON
  1368.  
  1369.     DECLARE @publisher_database_id int
  1370.     DECLARE @date datetime
  1371.     declare @originator_id int
  1372.  
  1373.     SELECT @date = GETDATE()
  1374.  
  1375.     -- Get publisher database id.
  1376.     SELECT @publisher_database_id = id from MSpublisher_databases where publisher_id = @publisher_id and 
  1377.         publisher_db = @publisher_db
  1378.     
  1379.     -- First insert into MS_repl_transactions
  1380.     IF @command_id = 1
  1381.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1382.          @xact_id,  @xact_seqno, @date)
  1383.  
  1384.     IF @1xact_id = 0x0
  1385.       goto INSERT_CMDS
  1386.     IF @1command_id = 1
  1387.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1388.          @1xact_id,  @1xact_seqno, @date)
  1389.  
  1390.     IF @2xact_id = 0x0
  1391.       goto INSERT_CMDS
  1392.     IF @2command_id = 1
  1393.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1394.          @2xact_id,  @2xact_seqno, @date)
  1395.     
  1396.     IF @3xact_id = 0x0
  1397.       goto INSERT_CMDS
  1398.     IF @3command_id = 1
  1399.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1400.          @3xact_id,  @3xact_seqno, @date)
  1401.  
  1402.     IF @4xact_id = 0x0
  1403.       goto INSERT_CMDS
  1404.     IF @4command_id = 1
  1405.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1406.         @4xact_id,  @4xact_seqno, @date)
  1407.  
  1408.     IF @5xact_id = 0x0
  1409.       goto INSERT_CMDS
  1410.  
  1411.     IF @5command_id = 1
  1412.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1413.          @5xact_id,  @5xact_seqno, @date)
  1414.  
  1415.     IF @6xact_id = 0x0
  1416.       goto INSERT_CMDS
  1417.     IF @6command_id = 1
  1418.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1419.          @6xact_id,  @6xact_seqno, @date)
  1420.  
  1421.     IF @7xact_id = 0x0
  1422.       goto INSERT_CMDS
  1423.     IF @7command_id = 1
  1424.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1425.          @7xact_id,  @7xact_seqno, @date)
  1426.  
  1427.     IF @8xact_id = 0x0
  1428.       goto INSERT_CMDS
  1429.     IF @8command_id = 1
  1430.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1431.          @8xact_id,  @8xact_seqno, @date)
  1432.  
  1433.     IF @9xact_id = 0x0
  1434.       goto INSERT_CMDS
  1435.     IF @9command_id = 1
  1436.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1437.          @9xact_id,  @9xact_seqno, @date)
  1438.  
  1439.     IF @10xact_id = 0x0
  1440.       goto INSERT_CMDS
  1441.     IF @10command_id = 1
  1442.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1443.          @10xact_id,  @10xact_seqno, @date)
  1444.  
  1445.     IF @11xact_id = 0x0
  1446.       goto INSERT_CMDS
  1447.     IF @11command_id = 1
  1448.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1449.          @11xact_id,  @11xact_seqno, @date)
  1450.  
  1451.     IF @12xact_id = 0x0
  1452.       goto INSERT_CMDS
  1453.     IF @12command_id = 1
  1454.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1455.          @12xact_id,  @12xact_seqno, @date)
  1456.  
  1457.     IF @13xact_id = 0x0
  1458.       goto INSERT_CMDS
  1459.     IF @13command_id = 1
  1460.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1461.          @13xact_id,  @13xact_seqno, @date)
  1462.  
  1463.     IF @14xact_id = 0x0
  1464.       goto INSERT_CMDS
  1465.     IF @14command_id = 1
  1466.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1467.          @14xact_id,  @14xact_seqno, @date)
  1468.  
  1469.     IF @15xact_id = 0x0
  1470.       goto INSERT_CMDS
  1471.     IF @15command_id = 1
  1472.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1473.          @15xact_id,  @15xact_seqno, @date)
  1474.  
  1475.     IF @16xact_id = 0x0
  1476.       goto INSERT_CMDS
  1477.     IF @16command_id = 1
  1478.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1479.          @16xact_id,  @16xact_seqno, @date)
  1480.  
  1481.     IF @17xact_id = 0x0
  1482.       goto INSERT_CMDS
  1483.     IF @17command_id = 1
  1484.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1485.          @17xact_id,  @17xact_seqno, @date)
  1486.  
  1487.     IF @18xact_id = 0x0
  1488.       goto INSERT_CMDS
  1489.     IF @18command_id = 1
  1490.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1491.          @18xact_id,  @18xact_seqno, @date)
  1492.  
  1493.     IF @19xact_id = 0x0
  1494.       goto INSERT_CMDS
  1495.     IF @19command_id = 1
  1496.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1497.          @19xact_id,  @19xact_seqno, @date)
  1498.  
  1499.     IF @20xact_id = 0x0
  1500.       goto INSERT_CMDS
  1501.     IF @20command_id = 1
  1502.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1503.          @20xact_id,  @20xact_seqno, @date)
  1504.  
  1505.     IF @21xact_id = 0x0
  1506.       goto INSERT_CMDS
  1507.     IF @21command_id = 1
  1508.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1509.          @21xact_id,  @21xact_seqno, @date)
  1510.  
  1511.     IF @22xact_id = 0x0
  1512.       goto INSERT_CMDS
  1513.     IF @22command_id = 1
  1514.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1515.          @22xact_id,  @22xact_seqno, @date)
  1516.  
  1517.     IF @23xact_id = 0x0
  1518.       goto INSERT_CMDS
  1519.     IF @23command_id = 1
  1520.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1521.          @23xact_id,  @23xact_seqno, @date)
  1522.  
  1523.     IF @24xact_id = 0x0
  1524.       goto INSERT_CMDS
  1525.     IF @24command_id = 1
  1526.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1527.          @24xact_id,  @24xact_seqno, @date)
  1528.  
  1529.     IF @25xact_id = 0x0
  1530.       goto INSERT_CMDS
  1531.     IF @25command_id = 1
  1532.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1533.          @25xact_id,  @25xact_seqno, @date)
  1534.  
  1535.     IF @26xact_id = 0x0
  1536.       goto INSERT_CMDS
  1537.     IF @26command_id = 1
  1538.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1539.          @26xact_id,  @26xact_seqno, @date)
  1540.  
  1541. INSERT_CMDS:
  1542.  
  1543.     -- Get the originator_id for the first command 
  1544.     if @originator <> N'' and @originator_db <> N'' and @originator is not null and @originator_db is not null 
  1545.     begin 
  1546.         set @originator_id = null select @originator_id = id from MSrepl_originators where
  1547.             publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@originator) and
  1548.             dbname = @originator_db
  1549.         if @originator_id is null
  1550.         begin
  1551.             insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1552.                 (@publisher_database_id, @originator, @originator_db)
  1553.             select @originator_id = @@identity
  1554.         end
  1555.     end
  1556.     else
  1557.         select @originator_id = 0
  1558.  
  1559.     -- Now insert into MSrepl_commands
  1560.     IF @command IS NOT NULL
  1561.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1562.             @xact_seqno,@type, @article_id, 
  1563.             @originator_id, 
  1564.             @command_id, @partial_command, @command)
  1565.  
  1566.     IF @1xact_id = 0x0
  1567.       return
  1568.  
  1569.     IF @1command IS NOT NULL
  1570.     begin
  1571.             if @1originator <> N'' and @1originator_db <> N'' and @1originator is not null and @1originator_db is not null 
  1572.             begin 
  1573.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1574.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@1originator) and
  1575.                     dbname = @1originator_db
  1576.                 if @originator_id is null
  1577.                 begin
  1578.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1579.                         (@publisher_database_id, @1originator, @1originator_db)
  1580.                     select @originator_id = @@identity
  1581.                 end
  1582.             end
  1583.             else
  1584.                 select @originator_id = 0
  1585.     
  1586.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1587.             @1xact_seqno,@1type, @1article_id, 
  1588.             @originator_id, 
  1589.             @1command_id, @1partial_command, @1command)
  1590.     end
  1591.  
  1592.     IF @2xact_id = 0x0
  1593.       return
  1594.     IF @2command IS NOT NULL
  1595.     begin
  1596.             if @2originator <> N'' and @2originator_db <> N'' and @2originator is not null and @2originator_db is not null 
  1597.             begin 
  1598.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1599.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@2originator) and
  1600.                     dbname = @2originator_db
  1601.                 if @originator_id is null
  1602.                 begin
  1603.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1604.                         (@publisher_database_id, @2originator, @2originator_db)
  1605.                     select @originator_id = @@identity
  1606.                 end
  1607.             end
  1608.             else
  1609.                 select @originator_id = 0
  1610.     
  1611.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1612.             @2xact_seqno,@2type, @2article_id, 
  1613.             @originator_id, 
  1614.             @2command_id, @2partial_command, @2command)
  1615.     end
  1616.  
  1617.     IF @3xact_id = 0x0
  1618.       return
  1619.     IF @3command IS NOT NULL
  1620.     begin
  1621.             if @3originator <> N'' and @3originator_db <> N'' and @3originator is not null and @3originator_db is not null 
  1622.             begin 
  1623.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1624.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@3originator) and
  1625.                     dbname = @3originator_db
  1626.                 if @originator_id is null
  1627.                 begin
  1628.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1629.                         (@publisher_database_id, @3originator, @3originator_db)
  1630.                     select @originator_id = @@identity
  1631.                 end
  1632.             end
  1633.             else
  1634.                 select @originator_id = 0
  1635.     
  1636.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1637.             @3xact_seqno,@3type, @3article_id, 
  1638.             @originator_id, 
  1639.             @3command_id, @3partial_command, @3command)
  1640.     end
  1641.  
  1642.     IF @4xact_id = 0x0
  1643.       return
  1644.     IF @4command IS NOT NULL
  1645.     begin
  1646.             if @4originator <> N'' and @4originator_db <> N'' and @4originator is not null and @4originator_db is not null 
  1647.             begin 
  1648.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1649.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@4originator) and
  1650.                     dbname = @4originator_db
  1651.                 if @originator_id is null
  1652.                 begin
  1653.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1654.                         (@publisher_database_id, @4originator, @4originator_db)
  1655.                     select @originator_id = @@identity
  1656.                 end
  1657.             end
  1658.             else
  1659.                 select @originator_id = 0
  1660.     
  1661.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1662.             @4xact_seqno,@4type, @4article_id, 
  1663.             @originator_id, 
  1664.             @4command_id, @4partial_command, @4command)
  1665.     end
  1666.  
  1667.     IF @5xact_id = 0x0
  1668.       return
  1669.     IF @5command IS NOT NULL
  1670.     begin
  1671.             if @5originator <> N'' and @5originator_db <> N'' and @5originator is not null and @5originator_db is not null 
  1672.             begin 
  1673.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1674.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@5originator) and
  1675.                     dbname = @5originator_db
  1676.                 if @originator_id is null
  1677.                 begin
  1678.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1679.                         (@publisher_database_id, @5originator, @5originator_db)
  1680.                     select @originator_id = @@identity
  1681.                 end
  1682.             end
  1683.             else
  1684.                 select @originator_id = 0
  1685.     
  1686.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1687.             @5xact_seqno,@5type, @5article_id, 
  1688.             @originator_id, 
  1689.             @5command_id, @5partial_command, @5command)
  1690.     end
  1691.  
  1692.     IF @6xact_id = 0x0
  1693.       return
  1694.     IF @6command IS NOT NULL
  1695.     begin
  1696.             if @6originator <> N'' and @6originator_db <> N'' and @6originator is not null and @6originator_db is not null 
  1697.             begin 
  1698.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1699.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@6originator) and
  1700.                     dbname = @6originator_db
  1701.                 if @originator_id is null
  1702.                 begin
  1703.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1704.                         (@publisher_database_id, @6originator, @6originator_db)
  1705.                     select @originator_id = @@identity
  1706.                 end
  1707.             end
  1708.             else
  1709.                 select @originator_id = 0
  1710.     
  1711.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1712.             @6xact_seqno,@6type, @6article_id, 
  1713.             @originator_id, 
  1714.             @6command_id, @6partial_command, @6command)
  1715.     end
  1716.  
  1717.     IF @7xact_id = 0x0
  1718.       return
  1719.     IF @7command IS NOT NULL
  1720.     begin
  1721.             if @7originator <> N'' and @7originator_db <> N'' and @7originator is not null and @7originator_db is not null 
  1722.             begin 
  1723.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1724.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@7originator) and
  1725.                     dbname = @7originator_db
  1726.                 if @originator_id is null
  1727.                 begin
  1728.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1729.                         (@publisher_database_id, @7originator, @7originator_db)
  1730.                     select @originator_id = @@identity
  1731.                 end
  1732.             end
  1733.             else
  1734.                 select @originator_id = 0
  1735.     
  1736.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1737.             @7xact_seqno,@7type, @7article_id, 
  1738.             @originator_id, 
  1739.             @7command_id, @7partial_command, @7command)
  1740.     end
  1741.  
  1742.     IF @8xact_id = 0x0
  1743.       return
  1744.     IF @8command IS NOT NULL
  1745.     begin
  1746.             if @8originator <> N'' and @8originator_db <> N'' and @8originator is not null and @8originator_db is not null 
  1747.             begin 
  1748.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1749.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@8originator) and
  1750.                     dbname = @8originator_db
  1751.                 if @originator_id is null
  1752.                 begin
  1753.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1754.                         (@publisher_database_id, @8originator, @8originator_db)
  1755.                     select @originator_id = @@identity
  1756.                 end
  1757.             end
  1758.             else
  1759.                 select @originator_id = 0
  1760.     
  1761.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1762.             @8xact_seqno,@8type, @8article_id, 
  1763.             @originator_id, 
  1764.             @8command_id, @8partial_command, @8command)
  1765.     end
  1766.  
  1767.     IF @9xact_id = 0x0
  1768.       return
  1769.     IF @9command IS NOT NULL
  1770.     begin
  1771.             if @9originator <> N'' and @9originator_db <> N'' and @9originator is not null and @9originator_db is not null 
  1772.             begin 
  1773.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1774.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@9originator) and
  1775.                     dbname = @9originator_db
  1776.                 if @originator_id is null
  1777.                 begin
  1778.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1779.                         (@publisher_database_id, @9originator, @9originator_db)
  1780.                     select @originator_id = @@identity
  1781.                 end
  1782.             end
  1783.             else
  1784.                 select @originator_id = 0
  1785.     
  1786.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1787.             @9xact_seqno,@9type, @9article_id, 
  1788.             @originator_id, 
  1789.             @9command_id, @9partial_command, @9command)
  1790.     end
  1791.  
  1792.     IF @10xact_id = 0x0
  1793.       return
  1794.     IF @10command IS NOT NULL
  1795.     begin
  1796.             if @10originator <> N'' and @10originator_db <> N'' and @10originator is not null and @10originator_db is not null 
  1797.             begin 
  1798.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1799.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@10originator) and
  1800.                     dbname = @10originator_db
  1801.                 if @originator_id is null
  1802.                 begin
  1803.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1804.                         (@publisher_database_id, @10originator, @10originator_db)
  1805.                     select @originator_id = @@identity
  1806.                 end
  1807.             end
  1808.             else
  1809.                 select @originator_id = 0
  1810.     
  1811.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1812.             @10xact_seqno,@10type, @10article_id, 
  1813.             @originator_id, 
  1814.             @10command_id, @10partial_command, @10command)
  1815.     end
  1816.  
  1817.     IF @11xact_id = 0x0
  1818.       return
  1819.     IF @11command IS NOT NULL
  1820.     begin
  1821.             if @11originator <> N'' and @11originator_db <> N'' and @11originator is not null and @11originator_db is not null 
  1822.             begin 
  1823.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1824.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@11originator) and
  1825.                     dbname = @11originator_db
  1826.                 if @originator_id is null
  1827.                 begin
  1828.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1829.                         (@publisher_database_id, @11originator, @11originator_db)
  1830.                     select @originator_id = @@identity
  1831.                 end
  1832.             end
  1833.             else
  1834.                 select @originator_id = 0
  1835.     
  1836.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1837.             @11xact_seqno,@11type, @11article_id, 
  1838.             @originator_id, 
  1839.             @11command_id, @11partial_command, @11command)
  1840.     end
  1841.  
  1842.     IF @12xact_id = 0x0
  1843.       return
  1844.     IF @12command IS NOT NULL
  1845.     begin
  1846.             if @12originator <> N'' and @12originator_db <> N'' and @12originator is not null and @12originator_db is not null 
  1847.             begin 
  1848.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1849.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@12originator) and
  1850.                     dbname = @12originator_db
  1851.                 if @originator_id is null
  1852.                 begin
  1853.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1854.                         (@publisher_database_id, @12originator, @12originator_db)
  1855.                     select @originator_id = @@identity
  1856.                 end
  1857.             end
  1858.             else
  1859.                 select @originator_id = 0
  1860.     
  1861.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1862.             @12xact_seqno,@12type, @12article_id, 
  1863.             @originator_id, 
  1864.             @12command_id, @12partial_command, @12command)
  1865.     end
  1866.  
  1867.  
  1868.     IF @13xact_id = 0x0
  1869.       return
  1870.     IF @13command IS NOT NULL
  1871.     begin
  1872.             if @13originator <> N'' and @13originator_db <> N'' and @13originator is not null and @13originator_db is not null 
  1873.             begin 
  1874.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1875.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@13originator) and
  1876.                     dbname = @13originator_db
  1877.                 if @originator_id is null
  1878.                 begin
  1879.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1880.                         (@publisher_database_id, @13originator, @13originator_db)
  1881.                     select @originator_id = @@identity
  1882.                 end
  1883.             end
  1884.             else
  1885.                 select @originator_id = 0
  1886.     
  1887.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1888.             @13xact_seqno,@13type, @13article_id, 
  1889.             @originator_id, 
  1890.             @13command_id, @13partial_command, @13command)
  1891.     end
  1892.  
  1893.     IF @14xact_id = 0x0
  1894.       return
  1895.     IF @14command IS NOT NULL
  1896.     begin
  1897.             if @14originator <> N'' and @14originator_db <> N'' and @14originator is not null and @14originator_db is not null 
  1898.             begin 
  1899.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1900.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@14originator) and
  1901.                     dbname = @14originator_db
  1902.                 if @originator_id is null
  1903.                 begin
  1904.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1905.                         (@publisher_database_id, @14originator, @14originator_db)
  1906.                     select @originator_id = @@identity
  1907.                 end
  1908.             end
  1909.             else
  1910.                 select @originator_id = 0
  1911.     
  1912.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1913.             @14xact_seqno,@14type, @14article_id, 
  1914.             @originator_id, 
  1915.             @14command_id, @14partial_command, @14command)
  1916.     end
  1917.  
  1918.  
  1919.     IF @15xact_id = 0x0
  1920.       return
  1921.     IF @15command IS NOT NULL
  1922.     begin
  1923.             if @15originator <> N'' and @15originator_db <> N'' and @15originator is not null and @15originator_db is not null 
  1924.             begin 
  1925.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1926.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@15originator) and
  1927.                     dbname = @15originator_db
  1928.                 if @originator_id is null
  1929.                 begin
  1930.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1931.                         (@publisher_database_id, @15originator, @15originator_db)
  1932.                     select @originator_id = @@identity
  1933.                 end
  1934.             end
  1935.             else
  1936.                 select @originator_id = 0
  1937.     
  1938.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1939.             @15xact_seqno,@15type, @15article_id, 
  1940.             @originator_id, 
  1941.             @15command_id, @15partial_command, @15command)
  1942.     end
  1943.  
  1944.     IF @16xact_id = 0x0
  1945.       return
  1946.     IF @16command IS NOT NULL
  1947.     begin
  1948.             if @16originator <> N'' and @16originator_db <> N'' and @16originator is not null and @16originator_db is not null 
  1949.             begin 
  1950.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1951.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@16originator) and
  1952.                     dbname = @16originator_db
  1953.                 if @originator_id is null
  1954.                 begin
  1955.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1956.                         (@publisher_database_id, @16originator, @16originator_db)
  1957.                     select @originator_id = @@identity
  1958.                 end
  1959.             end
  1960.             else
  1961.                 select @originator_id = 0
  1962.     
  1963.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1964.             @16xact_seqno,@16type, @16article_id, 
  1965.             @originator_id, 
  1966.             @16command_id, @16partial_command, @16command)
  1967.     end
  1968.  
  1969.  
  1970.     IF @17xact_id = 0x0
  1971.       return
  1972.     IF @17command IS NOT NULL
  1973.     begin
  1974.             if @17originator <> N'' and @17originator_db <> N'' and @17originator is not null and @17originator_db is not null 
  1975.             begin 
  1976.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1977.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@17originator) and
  1978.                     dbname = @17originator_db
  1979.                 if @originator_id is null
  1980.                 begin
  1981.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1982.                         (@publisher_database_id, @17originator, @17originator_db)
  1983.                     select @originator_id = @@identity
  1984.                 end
  1985.             end
  1986.             else
  1987.                 select @originator_id = 0
  1988.     
  1989.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1990.             @17xact_seqno,@17type, @17article_id, 
  1991.             @originator_id, 
  1992.             @17command_id, @17partial_command, @17command)
  1993.     end
  1994.  
  1995.  
  1996.     IF @18xact_id = 0x0
  1997.       return
  1998.     IF @18command IS NOT NULL
  1999.     begin
  2000.             if @18originator <> N'' and @18originator_db <> N'' and @18originator is not null and @18originator_db is not null 
  2001.             begin 
  2002.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2003.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@18originator) and
  2004.                     dbname = @18originator_db
  2005.                 if @originator_id is null
  2006.                 begin
  2007.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2008.                         (@publisher_database_id, @18originator, @18originator_db)
  2009.                     select @originator_id = @@identity
  2010.                 end
  2011.             end
  2012.             else
  2013.                 select @originator_id = 0
  2014.     
  2015.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2016.             @18xact_seqno,@18type, @18article_id, 
  2017.             @originator_id, 
  2018.             @18command_id, @18partial_command, @18command)
  2019.     end
  2020.  
  2021.  
  2022.     IF @19xact_id = 0x0
  2023.       return
  2024.     IF @19command IS NOT NULL
  2025.     begin
  2026.             if @19originator <> N'' and @19originator_db <> N'' and @19originator is not null and @19originator_db is not null 
  2027.             begin 
  2028.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2029.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@19originator) and
  2030.                     dbname = @19originator_db
  2031.                 if @originator_id is null
  2032.                 begin
  2033.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2034.                         (@publisher_database_id, @19originator, @19originator_db)
  2035.                     select @originator_id = @@identity
  2036.                 end
  2037.             end
  2038.             else
  2039.                 select @originator_id = 0
  2040.     
  2041.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2042.             @19xact_seqno,@19type, @19article_id, 
  2043.             @originator_id, 
  2044.             @19command_id, @19partial_command, @19command)
  2045.     end
  2046.  
  2047.  
  2048.     IF @20xact_id = 0x0
  2049.       return
  2050.     IF @20command IS NOT NULL
  2051.     begin
  2052.             if @20originator <> N'' and @20originator_db <> N'' and @20originator is not null and @20originator_db is not null 
  2053.             begin 
  2054.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2055.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@20originator) and
  2056.                     dbname = @20originator_db
  2057.                 if @originator_id is null
  2058.                 begin
  2059.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2060.                         (@publisher_database_id, @20originator, @20originator_db)
  2061.                     select @originator_id = @@identity
  2062.                 end
  2063.             end
  2064.             else
  2065.                 select @originator_id = 0
  2066.     
  2067.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2068.             @20xact_seqno,@20type, @20article_id, 
  2069.             @originator_id, 
  2070.             @20command_id, @20partial_command, @20command)
  2071.     end
  2072.  
  2073.     IF @21xact_id = 0x0
  2074.       return
  2075.     IF @21command IS NOT NULL
  2076.     begin
  2077.             if @21originator <> N'' and @21originator_db <> N'' and @21originator is not null and @21originator_db is not null 
  2078.             begin 
  2079.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2080.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@21originator) and
  2081.                     dbname = @21originator_db
  2082.                 if @originator_id is null
  2083.                 begin
  2084.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2085.                         (@publisher_database_id, @21originator, @21originator_db)
  2086.                     select @originator_id = @@identity
  2087.                 end
  2088.             end
  2089.             else
  2090.                 select @originator_id = 0
  2091.     
  2092.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2093.             @21xact_seqno,@21type, @21article_id, 
  2094.             @originator_id, 
  2095.             @21command_id, @21partial_command, @21command)
  2096.     end
  2097.  
  2098.     IF @22xact_id = 0x0
  2099.       return
  2100.     IF @22command IS NOT NULL
  2101.     begin
  2102.             if @22originator <> N'' and @22originator_db <> N'' and @22originator is not null and @22originator_db is not null 
  2103.             begin 
  2104.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2105.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@22originator) and
  2106.                     dbname = @22originator_db
  2107.                 if @originator_id is null
  2108.                 begin
  2109.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2110.                         (@publisher_database_id, @22originator, @22originator_db)
  2111.                     select @originator_id = @@identity
  2112.                 end
  2113.             end
  2114.             else
  2115.                 select @originator_id = 0
  2116.         end
  2117.     
  2118.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2119.             @22xact_seqno,@22type, @22article_id, 
  2120.             @originator_id, 
  2121.             @22command_id, @22partial_command, @22command)
  2122.  
  2123.  
  2124.     IF @23xact_id = 0x0
  2125.       return
  2126.     IF @23command IS NOT NULL
  2127.     begin
  2128.             if @23originator <> N'' and @23originator_db <> N'' and @23originator is not null and @23originator_db is not null 
  2129.             begin 
  2130.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2131.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@23originator) and
  2132.                     dbname = @23originator_db
  2133.                 if @originator_id is null
  2134.                 begin
  2135.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2136.                         (@publisher_database_id, @23originator, @23originator_db)
  2137.                     select @originator_id = @@identity
  2138.                 end
  2139.             end
  2140.             else
  2141.                 select @originator_id = 0
  2142.     
  2143.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2144.             @23xact_seqno,@23type, @23article_id, 
  2145.             @originator_id, 
  2146.             @23command_id, @23partial_command, @23command)
  2147.     end
  2148.  
  2149.     IF @24xact_id = 0x0
  2150.       return
  2151.     IF @24command IS NOT NULL
  2152.     begin
  2153.             if @24originator <> N'' and @24originator_db <> N'' and @24originator is not null and @24originator_db is not null 
  2154.             begin 
  2155.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2156.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@24originator) and
  2157.                     dbname = @24originator_db
  2158.                 if @originator_id is null
  2159.                 begin
  2160.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2161.                         (@publisher_database_id, @24originator, @24originator_db)
  2162.                     select @originator_id = @@identity
  2163.                 end
  2164.             end
  2165.             else
  2166.                 select @originator_id = 0
  2167.     
  2168.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2169.             @24xact_seqno,@24type, @24article_id, 
  2170.             @originator_id, 
  2171.             @24command_id, @24partial_command, @24command)
  2172.     end
  2173.  
  2174.  
  2175.     IF @25xact_id = 0x0
  2176.       return
  2177.     IF @25command IS NOT NULL
  2178.     begin
  2179.             if @25originator <> N'' and @25originator_db <> N'' and @25originator is not null and @25originator_db is not null 
  2180.             begin 
  2181.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2182.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@25originator) and
  2183.                     dbname = @25originator_db
  2184.                 if @originator_id is null
  2185.                 begin
  2186.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2187.                         (@publisher_database_id, @25originator, @25originator_db)
  2188.                     select @originator_id = @@identity
  2189.                 end
  2190.             end
  2191.             else
  2192.                 select @originator_id = 0
  2193.     
  2194.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2195.             @25xact_seqno,@25type, @25article_id, 
  2196.             @originator_id, 
  2197.             @25command_id, @25partial_command, @25command)
  2198.     end
  2199.  
  2200.  
  2201.     IF @26xact_id = 0x0
  2202.       return
  2203.     IF @26command IS NOT NULL
  2204.     begin
  2205.             if @26originator <> N'' and @26originator_db <> N'' and @26originator is not null and @26originator_db is not null 
  2206.             begin 
  2207.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2208.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@26originator) and
  2209.                     dbname = @26originator_db
  2210.                 if @originator_id is null
  2211.                 begin
  2212.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2213.                         (@publisher_database_id, @26originator, @26originator_db)
  2214.                     select @originator_id = @@identity
  2215.                 end
  2216.             end
  2217.             else
  2218.                 select @originator_id = 0
  2219.     
  2220.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2221.             @26xact_seqno,@26type, @26article_id, 
  2222.             @originator_id, 
  2223.             @26command_id, @26partial_command, @26command)
  2224.     end
  2225.  
  2226.  
  2227.     IF @@ERROR <> 0
  2228.       return (1)
  2229. GO
  2230.  
  2231. raiserror(15339,-1,-1,'sp_MSadd_repl_commands27hp6x')
  2232. GO
  2233.  
  2234. CREATE PROCEDURE sp_MSadd_repl_commands27hp6x
  2235. @publisher_id smallint,
  2236. @publisher_db sysname,
  2237. @data varbinary( 1575 ),
  2238. @1data varbinary(1575) = NULL,
  2239. @2data varbinary(1575) = NULL,
  2240. @3data varbinary(1575) = NULL,
  2241. @4data varbinary(1575) = NULL,
  2242. @5data varbinary(1575) = NULL,
  2243. @6data varbinary(1575) = NULL,
  2244. @7data varbinary(1575) = NULL,
  2245. @8data varbinary(1575) = NULL,
  2246. @9data varbinary(1575) = NULL,
  2247. @10data varbinary(1575) = NULL,
  2248. @11data varbinary(1575) = NULL,
  2249. @12data varbinary(1575) = NULL,
  2250. @13data varbinary(1575) = NULL,
  2251. @14data varbinary(1575) = NULL,
  2252. @15data varbinary(1575) = NULL,
  2253. @16data varbinary(1575) = NULL,
  2254. @17data varbinary(1575) = NULL,
  2255. @18data varbinary(1575) = NULL,
  2256. @19data varbinary(1575) = NULL,
  2257. @20data varbinary(1575) = NULL,
  2258. @21data varbinary(1575) = NULL,
  2259. @22data varbinary(1575) = NULL,
  2260. @23data varbinary(1575) = NULL,
  2261. @24data varbinary(1575) = NULL,
  2262. @25data varbinary(1575) = NULL,
  2263. @26data varbinary(1575) = NULL
  2264. AS
  2265.  
  2266.     SET NOCOUNT ON
  2267.  
  2268.     DECLARE @xact_id    varbinary(10)
  2269.     DECLARE @xact_seqno varbinary(10)
  2270.     DECLARE @article_id int
  2271.     DECLARE @command_id int
  2272.     DECLARE @type       int
  2273.     DECLARE @partial_command bit
  2274.     DECLARE @command    varbinary(1024)
  2275.  
  2276.     DECLARE @originator sysname
  2277.     DECLARE @originator_db sysname
  2278.  
  2279.     DECLARE @publisher_database_id int
  2280.     DECLARE @date datetime
  2281.     declare @originator_id int
  2282.  
  2283.     DECLARE @cmd_data_len  smallint
  2284.     DECLARE @orig_srv_len smallint
  2285.     DECLARE @orig_db_len  smallint
  2286.  
  2287.     SELECT @date = GETDATE()
  2288.  
  2289.     -- Get publisher database id.
  2290.     SELECT @publisher_database_id = id from MSpublisher_databases where publisher_id = @publisher_id and 
  2291.         publisher_db = @publisher_db
  2292.  
  2293.     -- First insert into MS_repl_transactions
  2294.     IF convert( int, substring( @data, 25, 4 ) ) = 1
  2295.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2296.          substring( @data, 1, 6 ), substring( @data, 11, 8 ), @date)
  2297.  
  2298.     IF @1data is null
  2299.       goto INSERT_CMDS
  2300.     IF convert( int, substring( @1data, 25, 4 ) ) = 1
  2301.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2302.          substring( @1data, 1, 6 ), substring( @1data, 11, 8 ), @date)
  2303.  
  2304.     IF @2data is null
  2305.       goto INSERT_CMDS
  2306.     IF convert( int, substring( @2data, 25, 4 ) ) = 1
  2307.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2308.          substring( @2data, 1, 6 ), substring( @2data, 11, 8 ), @date)
  2309.     
  2310.     IF @3data is null
  2311.       goto INSERT_CMDS
  2312.     IF convert( int, substring( @3data, 25, 4 ) ) = 1
  2313.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2314.          substring( @3data, 1, 6 ), substring( @3data, 11, 8 ), @date)
  2315.  
  2316.     IF @4data is null
  2317.       goto INSERT_CMDS
  2318.     IF convert( int, substring( @4data, 25, 4 ) ) = 1
  2319.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2320.          substring( @4data, 1, 6 ), substring( @4data, 11, 8 ), @date)
  2321.  
  2322.     IF @5data is null
  2323.       goto INSERT_CMDS
  2324.     IF convert( int, substring( @5data, 25, 4 ) ) = 1
  2325.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2326.          substring( @5data, 1, 6 ), substring( @5data, 11, 8 ), @date)
  2327.  
  2328.     IF @6data is null
  2329.       goto INSERT_CMDS
  2330.     IF convert( int, substring( @6data, 25, 4 ) ) = 1
  2331.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2332.          substring( @6data, 1, 6 ), substring( @6data, 11, 8 ), @date)
  2333.  
  2334.     IF @7data is null
  2335.       goto INSERT_CMDS
  2336.     IF convert( int, substring( @7data, 25, 4 ) ) = 1
  2337.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2338.          substring( @7data, 1, 6 ), substring( @7data, 11, 8 ), @date)
  2339.  
  2340.     IF @8data is null
  2341.       goto INSERT_CMDS
  2342.     IF convert( int, substring( @8data, 25, 4 ) ) = 1
  2343.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2344.          substring( @8data, 1, 6 ), substring( @8data, 11, 8 ), @date)
  2345.  
  2346.     IF @9data is null
  2347.       goto INSERT_CMDS
  2348.     IF convert( int, substring( @9data, 25, 4 ) ) = 1
  2349.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2350.          substring( @9data, 1, 6 ), substring( @9data, 11, 8 ), @date)
  2351.  
  2352.     IF @10data is null
  2353.       goto INSERT_CMDS
  2354.     IF convert( int, substring( @10data, 25, 4 ) ) = 1
  2355.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2356.          substring( @10data, 1, 6 ), substring( @10data, 11, 8 ), @date)
  2357.  
  2358.     IF @11data is null
  2359.       goto INSERT_CMDS
  2360.     IF convert( int, substring( @11data, 25, 4 ) ) = 1
  2361.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2362.          substring( @11data, 1, 6 ), substring( @11data, 11, 8 ), @date)
  2363.  
  2364.     IF @12data is null
  2365.       goto INSERT_CMDS
  2366.     IF convert( int, substring( @12data, 25, 4 ) ) = 1
  2367.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2368.          substring( @12data, 1, 6 ), substring( @12data, 11, 8 ), @date)
  2369.  
  2370.     IF @13data is null
  2371.       goto INSERT_CMDS
  2372.     IF convert( int, substring( @13data, 25, 4 ) ) = 1
  2373.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2374.          substring( @13data, 1, 6 ), substring( @13data, 11, 8 ), @date)
  2375.  
  2376.     IF @14data is null
  2377.       goto INSERT_CMDS
  2378.     IF convert( int, substring( @14data, 25, 4 ) ) = 1
  2379.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2380.          substring( @14data, 1, 6 ), substring( @14data, 11, 8 ), @date)
  2381.  
  2382.     IF @15data is null
  2383.       goto INSERT_CMDS
  2384.     IF convert( int, substring( @15data, 25, 4 ) ) = 1
  2385.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2386.          substring( @15data, 1, 6 ), substring( @15data, 11, 8 ), @date)
  2387.  
  2388.     IF @16data is null
  2389.       goto INSERT_CMDS
  2390.     IF convert( int, substring( @16data, 25, 4 ) ) = 1
  2391.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2392.          substring( @16data, 1, 6 ), substring( @16data, 11, 8 ), @date)
  2393.  
  2394.     IF @17data is null
  2395.       goto INSERT_CMDS
  2396.     IF convert( int, substring( @17data, 25, 4 ) ) = 1
  2397.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2398.          substring( @17data, 1, 6 ), substring( @17data, 11, 8 ), @date)
  2399.  
  2400.     IF @18data is null
  2401.       goto INSERT_CMDS
  2402.     IF convert( int, substring( @18data, 25, 4 ) ) = 1
  2403.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2404.          substring( @18data, 1, 6 ), substring( @18data, 11, 8 ), @date)
  2405.  
  2406.     IF @19data is null
  2407.       goto INSERT_CMDS
  2408.     IF convert( int, substring( @19data, 25, 4 ) ) = 1
  2409.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2410.          substring( @19data, 1, 6 ), substring( @19data, 11, 8 ), @date)
  2411.  
  2412.     IF @20data is null
  2413.       goto INSERT_CMDS
  2414.     IF convert( int, substring( @20data, 25, 4 ) ) = 1
  2415.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2416.          substring( @20data, 1, 6 ), substring( @20data, 11, 8 ), @date)
  2417.  
  2418.     IF @21data is null
  2419.       goto INSERT_CMDS
  2420.     IF convert( int, substring( @21data, 25, 4 ) ) = 1
  2421.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2422.          substring( @21data, 1, 6 ), substring( @21data, 11, 8 ), @date)
  2423.  
  2424.     IF @22data is null
  2425.       goto INSERT_CMDS
  2426.     IF convert( int, substring( @22data, 25, 4 ) ) = 1
  2427.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2428.          substring( @22data, 1, 6 ), substring( @22data, 11, 8 ), @date)
  2429.  
  2430.     IF @23data is null
  2431.       goto INSERT_CMDS
  2432.     IF convert( int, substring( @23data, 25, 4 ) ) = 1
  2433.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2434.          substring( @23data, 1, 6 ), substring( @23data, 11, 8 ), @date)
  2435.  
  2436.     IF @24data is null
  2437.       goto INSERT_CMDS
  2438.     IF convert( int, substring( @24data, 25, 4 ) ) = 1
  2439.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2440.          substring( @24data, 1, 6 ), substring( @24data, 11, 8 ), @date)
  2441.  
  2442.     IF @25data is null
  2443.       goto INSERT_CMDS
  2444.     IF convert( int, substring( @25data, 25, 4 ) ) = 1
  2445.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2446.          substring( @25data, 1, 6 ), substring( @25data, 11, 8 ), @date)
  2447.  
  2448.     IF @26data is null
  2449.       goto INSERT_CMDS
  2450.     IF convert( int, substring( @26data, 25, 4 ) ) = 1
  2451.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2452.          substring( @26data, 1, 6 ), substring( @26data, 11, 8 ), @date)
  2453.  
  2454. INSERT_CMDS:
  2455.  
  2456.     if datalength( @data ) > 39
  2457.     begin
  2458.         -- Get the originator_id for the first command 
  2459.         select @cmd_data_len = substring( @data, 34, 2 )
  2460.         select @orig_srv_len = substring( @data, 36, 2 )
  2461.         select @orig_db_len = substring( @data, 38, 2 )
  2462.  
  2463.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2464.         begin 
  2465.             set @originator_id = null 
  2466.             select @originator_id = id from MSrepl_originators where
  2467.                 publisher_database_id = @publisher_database_id 
  2468.                 and UPPER(srvname) = UPPER(convert(sysname, substring( @data, 40 + @cmd_data_len, @orig_srv_len )))
  2469.                 and dbname = substring( @data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2470.             if @originator_id is null
  2471.             begin
  2472.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2473.                     (@publisher_database_id, substring( @data, 40 + @cmd_data_len, @orig_srv_len ), substring( @data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2474.                 select @originator_id = @@identity
  2475.             end
  2476.         end
  2477.         else
  2478.             select @originator_id = 0
  2479.  
  2480.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2481.             substring(@data,11,8),
  2482.             substring(@data,29,4), 
  2483.             substring(@data,21,4), 
  2484.             @originator_id, 
  2485.             substring(@data,25,4), 
  2486.             convert(bit,substring(@data,33,1)), 
  2487.             substring(@data,40,@cmd_data_len) )
  2488.     end
  2489.     
  2490.     IF @1data is null
  2491.       return
  2492.     IF datalength( @1data ) > 39
  2493.     begin
  2494.         -- Get the originator_id for the first command 
  2495.         select @cmd_data_len = substring( @1data, 34, 2 )
  2496.         select @orig_srv_len = substring( @1data, 36, 2 )
  2497.         select @orig_db_len = substring( @1data, 38, 2 )
  2498.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2499.         begin 
  2500.             set @originator_id = null 
  2501.             select @originator_id = id from MSrepl_originators where
  2502.                 publisher_database_id = @publisher_database_id 
  2503.                 and UPPER(srvname) = UPPER(convert(sysname, substring( @1data, 40 + @cmd_data_len, @orig_srv_len )))
  2504.                 and dbname = substring( @1data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2505.             if @originator_id is null
  2506.             begin
  2507.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2508.                     (@publisher_database_id, substring( @1data, 40 + @cmd_data_len, @orig_srv_len ), substring( @1data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2509.                 select @originator_id = @@identity
  2510.             end
  2511.         end
  2512.         else
  2513.             select @originator_id = 0
  2514.  
  2515.         -- Now insert into MSrepl_commands
  2516.  
  2517.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2518.             substring(@1data,11,8),
  2519.             substring(@1data,29,4), 
  2520.             substring(@1data,21,4), 
  2521.             @originator_id, 
  2522.             substring(@1data,25,4), 
  2523.             convert(bit,substring(@1data,33,1)), 
  2524.             substring(@1data,40,@cmd_data_len) )
  2525.     end
  2526.  
  2527.     IF @2data is null
  2528.       return
  2529.     IF datalength( @2data ) > 39
  2530.     begin
  2531.         -- Get the originator_id for the first command 
  2532.         select @cmd_data_len = substring( @2data, 34, 2 )
  2533.         select @orig_srv_len = substring( @2data, 36, 2 )
  2534.         select @orig_db_len = substring( @2data, 38, 2 )
  2535.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2536.         begin 
  2537.             set @originator_id = null 
  2538.             select @originator_id = id from MSrepl_originators where
  2539.                 publisher_database_id = @publisher_database_id 
  2540.                 and UPPER(srvname) = UPPER(convert(sysname, substring( @2data, 40 + @cmd_data_len, @orig_srv_len )))
  2541.                 and dbname = substring( @2data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2542.             if @originator_id is null
  2543.             begin
  2544.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2545.                     (@publisher_database_id, substring( @2data, 40 + @cmd_data_len, @orig_srv_len ), substring( @2data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2546.                 select @originator_id = @@identity
  2547.             end
  2548.         end
  2549.         else
  2550.             select @originator_id = 0
  2551.  
  2552.         -- Now insert into MSrepl_commands
  2553.  
  2554.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2555.             substring(@2data,11 ,8),
  2556.             substring(@2data,29 ,4), 
  2557.             substring(@2data,21 ,4), 
  2558.             @originator_id, 
  2559.             substring(@2data,25 ,4), 
  2560.             convert(bit,substring(@2data,33 ,1)), 
  2561.             substring(@2data,40,@cmd_data_len) )
  2562.     end
  2563.  
  2564.     IF @3data is null
  2565.       return
  2566.     IF datalength( @3data ) > 39
  2567.     begin
  2568.         -- Get the originator_id for the first command 
  2569.         select @cmd_data_len = substring( @3data, 34, 2 )
  2570.         select @orig_srv_len = substring( @3data, 36, 2 )
  2571.         select @orig_db_len = substring( @3data, 38, 2 )
  2572.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2573.         begin 
  2574.             set @originator_id = null 
  2575.             select @originator_id = id from MSrepl_originators where
  2576.                 publisher_database_id = @publisher_database_id 
  2577.                 and UPPER(srvname) = UPPER(convert(sysname, substring( @3data, 40 + @cmd_data_len, @orig_srv_len )))
  2578.                 and dbname = substring( @3data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2579.             if @originator_id is null
  2580.             begin
  2581.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2582.                     (@publisher_database_id, substring( @3data, 40 + @cmd_data_len, @orig_srv_len ), substring( @3data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2583.                 select @originator_id = @@identity
  2584.             end
  2585.         end
  2586.         else
  2587.             select @originator_id = 0
  2588.  
  2589.         -- Now insert into MSrepl_commands
  2590.  
  2591.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2592.             substring(@3data,11 ,8),
  2593.             substring(@3data,29 ,4), 
  2594.             substring(@3data,21 ,4), 
  2595.             @originator_id, 
  2596.             substring(@3data,25 ,4), 
  2597.             convert(bit,substring(@3data,33 ,1)), 
  2598.             substring(@3data,40,@cmd_data_len) )
  2599.     end
  2600.  
  2601.     IF @4data is null
  2602.       return
  2603.     IF datalength( @4data ) > 39
  2604.     begin
  2605.         -- Get the originator_id for the first command 
  2606.         select @cmd_data_len = substring( @4data, 34, 2 )
  2607.         select @orig_srv_len = substring( @4data, 36, 2 )
  2608.         select @orig_db_len = substring( @4data, 38, 2 )
  2609.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2610.         begin 
  2611.             set @originator_id = null 
  2612.             select @originator_id = id from MSrepl_originators where
  2613.                 publisher_database_id = @publisher_database_id 
  2614.                 and UPPER(srvname) = UPPER(convert(sysname, substring( @4data, 40 + @cmd_data_len, @orig_srv_len )))
  2615.                 and dbname = substring( @4data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2616.             if @originator_id is null
  2617.             begin
  2618.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2619.                     (@publisher_database_id, substring( @4data, 40 + @cmd_data_len, @orig_srv_len ), substring( @4data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2620.                 select @originator_id = @@identity
  2621.             end
  2622.         end
  2623.         else
  2624.             select @originator_id = 0
  2625.  
  2626.         -- Now insert into MSrepl_commands
  2627.  
  2628.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2629.             substring(@4data,11 ,8),
  2630.             substring(@4data,29 ,4), 
  2631.             substring(@4data,21 ,4), 
  2632.             @originator_id, 
  2633.             substring(@4data,25 ,4), 
  2634.             convert(bit,substring(@4data,33 ,1)), 
  2635.             substring(@4data,40,@cmd_data_len) )
  2636.     end
  2637.  
  2638.     IF @5data is null
  2639.       return
  2640.     IF datalength( @5data ) > 39
  2641.     begin
  2642.         -- Get the originator_id for the first command 
  2643.         select @cmd_data_len = substring( @5data, 34, 2 )
  2644.         select @orig_srv_len = substring( @5data, 36, 2 )
  2645.         select @orig_db_len = substring( @5data, 38, 2 )
  2646.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2647.         begin 
  2648.             set @originator_id = null 
  2649.             select @originator_id = id from MSrepl_originators where
  2650.                 publisher_database_id = @publisher_database_id 
  2651.                 and UPPER(srvname) = UPPER(convert(sysname, substring( @5data, 40 + @cmd_data_len, @orig_srv_len )))
  2652.                 and dbname = substring( @5data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2653.             if @originator_id is null
  2654.             begin
  2655.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2656.                     (@publisher_database_id, substring( @5data, 40 + @cmd_data_len, @orig_srv_len ), substring( @5data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2657.                 select @originator_id = @@identity
  2658.             end
  2659.         end
  2660.         else
  2661.             select @originator_id = 0
  2662.  
  2663.         -- Now insert into MSrepl_commands
  2664.  
  2665.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2666.             substring(@5data,11 ,8),
  2667.             substring(@5data,29 ,4), 
  2668.             substring(@5data,21 ,4), 
  2669.             @originator_id, 
  2670.             substring(@5data,25 ,4), 
  2671.             convert(bit,substring(@5data,33 ,1)), 
  2672.             substring(@5data,40,@cmd_data_len) )
  2673.     end
  2674.  
  2675.     IF @6data is null
  2676.       return
  2677.     IF datalength( @6data ) > 39
  2678.     begin
  2679.         -- Get the originator_id for the first command 
  2680.         select @cmd_data_len = substring( @6data, 34, 2 )
  2681.         select @orig_srv_len = substring( @6data, 36, 2 )
  2682.         select @orig_db_len = substring( @6data, 38, 2 )
  2683.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2684.         begin 
  2685.             set @originator_id = null 
  2686.             select @originator_id = id from MSrepl_originators where
  2687.                 publisher_database_id = @publisher_database_id 
  2688.                 and UPPER(srvname) = UPPER(convert(sysname, substring( @6data, 40 + @cmd_data_len, @orig_srv_len )))
  2689.                 and dbname = substring( @6data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2690.             if @originator_id is null
  2691.             begin
  2692.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2693.                     (@publisher_database_id, substring( @6data, 40 + @cmd_data_len, @orig_srv_len ), substring( @6data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2694.                 select @originator_id = @@identity
  2695.             end
  2696.         end
  2697.         else
  2698.             select @originator_id = 0
  2699.  
  2700.         -- Now insert into MSrepl_commands
  2701.  
  2702.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2703.             substring(@6data,11 ,8),
  2704.             substring(@6data,29 ,4), 
  2705.             substring(@6data,21 ,4), 
  2706.             @originator_id, 
  2707.             substring(@6data,25 ,4), 
  2708.             convert(bit,substring(@6data,33 ,1)), 
  2709.             substring(@6data,40,@cmd_data_len) )
  2710.     end
  2711.  
  2712.     IF @7data is null
  2713.       return
  2714.     IF datalength( @7data ) > 39
  2715.     begin
  2716.         -- Get the originator_id for the first command 
  2717.         select @cmd_data_len = substring( @7data, 34, 2 )
  2718.         select @orig_srv_len = substring( @7data, 36, 2 )
  2719.         select @orig_db_len = substring( @7data, 38, 2 )
  2720.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2721.         begin 
  2722.             set @originator_id = null 
  2723.             select @originator_id = id from MSrepl_originators where
  2724.                 publisher_database_id = @publisher_database_id 
  2725.                 and UPPER(srvname) = UPPER(convert(sysname, substring( @7data, 40 + @cmd_data_len, @orig_srv_len )))
  2726.                 and dbname = substring( @7data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2727.             if @originator_id is null
  2728.             begin
  2729.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2730.                     (@publisher_database_id, substring( @7data, 40 + @cmd_data_len, @orig_srv_len ), substring( @7data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2731.                 select @originator_id = @@identity
  2732.             end
  2733.         end
  2734.         else
  2735.             select @originator_id = 0
  2736.  
  2737.         -- Now insert into MSrepl_commands
  2738.  
  2739.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2740.             substring(@7data,11 ,8),
  2741.             substring(@7data,29 ,4), 
  2742.             substring(@7data,21 ,4), 
  2743.             @originator_id, 
  2744.             substring(@7data,25 ,4), 
  2745.             convert(bit,substring(@7data,33 ,1)), 
  2746.             substring(@7data,40,@cmd_data_len) )
  2747.     end
  2748.  
  2749.     IF @8data is null
  2750.       return
  2751.     IF datalength( @8data ) > 39
  2752.     begin
  2753.         -- Get the originator_id for the first command 
  2754.         select @cmd_data_len = substring( @8data, 34, 2 )
  2755.         select @orig_srv_len = substring( @8data, 36, 2 )
  2756.         select @orig_db_len = substring( @8data, 38, 2 )
  2757.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2758.         begin 
  2759.             set @originator_id = null 
  2760.             select @originator_id = id from MSrepl_originators where
  2761.                 publisher_database_id = @publisher_database_id 
  2762.                 and UPPER(srvname) = UPPER(convert(sysname, substring( @8data, 40 + @cmd_data_len, @orig_srv_len )))
  2763.                 and dbname = substring( @8data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2764.             if @originator_id is null
  2765.             begin
  2766.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2767.                     (@publisher_database_id, substring( @8data, 40 + @cmd_data_len, @orig_srv_len ), substring( @8data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2768.                 select @originator_id = @@identity
  2769.             end
  2770.         end
  2771.         else
  2772.             select @originator_id = 0
  2773.  
  2774.         -- Now insert into MSrepl_commands
  2775.  
  2776.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2777.             substring(@8data,11 ,8),
  2778.             substring(@8data,29 ,4), 
  2779.             substring(@8data,21 ,4), 
  2780.             @originator_id, 
  2781.             substring(@8data,25 ,4), 
  2782.             convert(bit,substring(@8data,33 ,1)), 
  2783.             substring(@8data,40,@cmd_data_len) )
  2784.     end
  2785.  
  2786.     IF @9data is null
  2787.       return
  2788.     IF datalength( @9data ) > 39
  2789.     begin
  2790.         -- Get the originator_id for the first command 
  2791.         select @cmd_data_len = substring( @9data, 34, 2 )
  2792.         select @orig_srv_len = substring( @9data, 36, 2 )
  2793.         select @orig_db_len = substring( @9data, 38, 2 )
  2794.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2795.         begin 
  2796.             set @originator_id = null 
  2797.             select @originator_id = id from MSrepl_originators where
  2798.                 publisher_database_id = @publisher_database_id 
  2799.                 and UPPER(srvname) = UPPER(convert(sysname, substring( @9data, 40 + @cmd_data_len, @orig_srv_len )))
  2800.                 and dbname = substring( @9data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2801.             if @originator_id is null
  2802.             begin
  2803.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2804.                     (@publisher_database_id, substring( @9data, 40 + @cmd_data_len, @orig_srv_len ), substring( @9data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2805.                 select @originator_id = @@identity
  2806.             end
  2807.         end
  2808.         else
  2809.             select @originator_id = 0
  2810.  
  2811.         -- Now insert into MSrepl_commands
  2812.  
  2813.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2814.             substring(@9data,11 ,8),
  2815.             substring(@9data,29 ,4), 
  2816.             substring(@9data,21 ,4), 
  2817.             @originator_id, 
  2818.             substring(@9data,25 ,4), 
  2819.             convert(bit,substring(@9data,33 ,1)), 
  2820.             substring(@9data,40,@cmd_data_len) )
  2821.     end
  2822.  
  2823.     IF @10data is null
  2824.       return
  2825.     IF datalength( @10data ) > 39
  2826.     begin
  2827.         -- Get the originator_id for the first command 
  2828.         select @cmd_data_len = substring( @10data, 34, 2 )
  2829.         select @orig_srv_len = substring( @10data, 36, 2 )
  2830.         select @orig_db_len = substring( @10data, 38, 2 )
  2831.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2832.         begin 
  2833.             set @originator_id = null 
  2834.             select @originator_id = id from MSrepl_originators where
  2835.                 publisher_database_id = @publisher_database_id 
  2836.                 and UPPER(srvname) = upper(convert(sysname, substring( @10data, 40 + @cmd_data_len, @orig_srv_len )))
  2837.                 and dbname = substring( @10data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2838.             if @originator_id is null
  2839.             begin
  2840.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2841.                     (@publisher_database_id, substring( @10data, 40 + @cmd_data_len, @orig_srv_len ), substring( @10data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2842.                 select @originator_id = @@identity
  2843.             end
  2844.         end
  2845.         else
  2846.             select @originator_id = 0
  2847.  
  2848.         -- Now insert into MSrepl_commands
  2849.  
  2850.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2851.             substring(@10data,11 ,8),
  2852.             substring(@10data,29 ,4), 
  2853.             substring(@10data,21 ,4), 
  2854.             @originator_id, 
  2855.             substring(@10data,25 ,4), 
  2856.             convert(bit,substring(@10data,33 ,1)), 
  2857.             substring(@10data,40,@cmd_data_len) )
  2858.     end
  2859.  
  2860.     IF @11data is null
  2861.       return
  2862.     IF datalength( @11data ) > 39
  2863.     begin
  2864.         -- Get the originator_id for the first command 
  2865.         select @cmd_data_len = substring( @11data, 34, 2 )
  2866.         select @orig_srv_len = substring( @11data, 36, 2 )
  2867.         select @orig_db_len = substring( @11data, 38, 2 )
  2868.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2869.         begin 
  2870.             set @originator_id = null 
  2871.             select @originator_id = id from MSrepl_originators where
  2872.                 publisher_database_id = @publisher_database_id 
  2873.                 and UPPER(srvname) = upper(convert(sysname, substring( @11data, 40 + @cmd_data_len, @orig_srv_len )))
  2874.                 and dbname = substring( @11data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2875.             if @originator_id is null
  2876.             begin
  2877.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2878.                     (@publisher_database_id, substring( @11data, 40 + @cmd_data_len, @orig_srv_len ), substring( @11data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2879.                 select @originator_id = @@identity
  2880.             end
  2881.         end
  2882.         else
  2883.             select @originator_id = 0
  2884.  
  2885.         -- Now insert into MSrepl_commands
  2886.  
  2887.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2888.             substring(@11data,11 ,8),
  2889.             substring(@11data,29 ,4), 
  2890.             substring(@11data,21 ,4), 
  2891.             @originator_id, 
  2892.             substring(@11data,25 ,4), 
  2893.             convert(bit,substring(@11data,33 ,1)), 
  2894.             substring(@11data,40,@cmd_data_len) )
  2895.     end
  2896.  
  2897.     IF @12data is null
  2898.       return
  2899.     IF datalength( @12data ) > 39
  2900.     begin
  2901.         -- Get the originator_id for the first command 
  2902.         select @cmd_data_len = substring( @12data, 34, 2 )
  2903.         select @orig_srv_len = substring( @12data, 36, 2 )
  2904.         select @orig_db_len = substring( @12data, 38, 2 )
  2905.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2906.         begin 
  2907.             set @originator_id = null 
  2908.             select @originator_id = id from MSrepl_originators where
  2909.                 publisher_database_id = @publisher_database_id 
  2910.                 and UPPER(srvname) = upper(convert(sysname, substring( @12data, 40 + @cmd_data_len, @orig_srv_len )))
  2911.                 and dbname = substring( @12data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2912.             if @originator_id is null
  2913.             begin
  2914.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2915.                     (@publisher_database_id, substring( @12data, 40 + @cmd_data_len, @orig_srv_len ), substring( @12data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2916.                 select @originator_id = @@identity
  2917.             end
  2918.         end
  2919.         else
  2920.             select @originator_id = 0
  2921.  
  2922.         -- Now insert into MSrepl_commands
  2923.  
  2924.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2925.             substring(@12data,11 ,8),
  2926.             substring(@12data,29 ,4), 
  2927.             substring(@12data,21 ,4), 
  2928.             @originator_id, 
  2929.             substring(@12data,25 ,4), 
  2930.             convert(bit,substring(@12data,33 ,1)), 
  2931.             substring(@12data,40,@cmd_data_len) )
  2932.     end
  2933.  
  2934.  
  2935.     IF @13data is null
  2936.       return
  2937.     IF datalength( @13data ) > 39
  2938.     begin
  2939.         -- Get the originator_id for the first command 
  2940.         select @cmd_data_len = substring( @13data, 34, 2 )
  2941.         select @orig_srv_len = substring( @13data, 36, 2 )
  2942.         select @orig_db_len = substring( @13data, 38, 2 )
  2943.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2944.         begin 
  2945.             set @originator_id = null 
  2946.             select @originator_id = id from MSrepl_originators where
  2947.                 publisher_database_id = @publisher_database_id 
  2948.                 and UPPER(srvname) = upper(convert(sysname, substring( @13data, 40 + @cmd_data_len, @orig_srv_len )))
  2949.                 and dbname = substring( @13data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2950.             if @originator_id is null
  2951.             begin
  2952.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2953.                     (@publisher_database_id, substring( @13data, 40 + @cmd_data_len, @orig_srv_len ), substring( @13data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2954.                 select @originator_id = @@identity
  2955.             end
  2956.         end
  2957.         else
  2958.             select @originator_id = 0
  2959.  
  2960.         -- Now insert into MSrepl_commands
  2961.  
  2962.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2963.             substring(@13data,11 ,8),
  2964.             substring(@13data,29 ,4), 
  2965.             substring(@13data,21 ,4), 
  2966.             @originator_id, 
  2967.             substring(@13data,25 ,4), 
  2968.             convert(bit,substring(@13data,33 ,1)), 
  2969.             substring(@13data,40,@cmd_data_len) )
  2970.     end
  2971.  
  2972.     IF @14data is null
  2973.       return
  2974.     IF datalength( @14data ) > 39
  2975.     begin
  2976.         -- Get the originator_id for the first command 
  2977.         select @cmd_data_len = substring( @14data, 34, 2 )
  2978.         select @orig_srv_len = substring( @14data, 36, 2 )
  2979.         select @orig_db_len = substring( @14data, 38, 2 )
  2980.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2981.         begin 
  2982.             set @originator_id = null 
  2983.             select @originator_id = id from MSrepl_originators where
  2984.                 publisher_database_id = @publisher_database_id 
  2985.                 and UPPER(srvname) = upper(convert(sysname, substring( @14data, 40 + @cmd_data_len, @orig_srv_len )))
  2986.                 and dbname = substring( @14data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2987.             if @originator_id is null
  2988.             begin
  2989.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2990.                     (@publisher_database_id, substring( @14data, 40 + @cmd_data_len, @orig_srv_len ), substring( @14data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2991.                 select @originator_id = @@identity
  2992.             end
  2993.         end
  2994.         else
  2995.             select @originator_id = 0
  2996.  
  2997.         -- Now insert into MSrepl_commands
  2998.  
  2999.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3000.             substring(@14data,11 ,8),
  3001.             substring(@14data,29 ,4), 
  3002.             substring(@14data,21 ,4), 
  3003.             @originator_id, 
  3004.             substring(@14data,25 ,4), 
  3005.             convert(bit,substring(@14data,33 ,1)), 
  3006.             substring(@14data,40,@cmd_data_len) )
  3007.     end
  3008.  
  3009.  
  3010.     IF @15data is null
  3011.       return
  3012.     IF datalength( @15data ) > 39
  3013.     begin
  3014.         -- Get the originator_id for the first command 
  3015.         select @cmd_data_len = substring( @15data, 34, 2 )
  3016.         select @orig_srv_len = substring( @15data, 36, 2 )
  3017.         select @orig_db_len = substring( @15data, 38, 2 )
  3018.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3019.         begin 
  3020.             set @originator_id = null 
  3021.             select @originator_id = id from MSrepl_originators where
  3022.                 publisher_database_id = @publisher_database_id 
  3023.                 and UPPER(srvname) = upper(convert(sysname, substring( @15data, 40 + @cmd_data_len, @orig_srv_len )))
  3024.                 and dbname = substring( @15data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3025.             if @originator_id is null
  3026.             begin
  3027.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3028.                     (@publisher_database_id, substring( @15data, 40 + @cmd_data_len, @orig_srv_len ), substring( @15data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3029.                 select @originator_id = @@identity
  3030.             end
  3031.         end
  3032.         else
  3033.             select @originator_id = 0
  3034.  
  3035.         -- Now insert into MSrepl_commands
  3036.  
  3037.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3038.             substring(@15data,11 ,8),
  3039.             substring(@15data,29 ,4), 
  3040.             substring(@15data,21 ,4), 
  3041.             @originator_id, 
  3042.             substring(@15data,25 ,4), 
  3043.             convert(bit,substring(@15data,33 ,1)), 
  3044.             substring(@15data,40,@cmd_data_len) )
  3045.     end
  3046.  
  3047.     IF @16data is null
  3048.       return
  3049.     IF datalength( @16data ) > 39
  3050.     begin
  3051.         -- Get the originator_id for the first command 
  3052.         select @cmd_data_len = substring( @16data, 34, 2 )
  3053.         select @orig_srv_len = substring( @16data, 36, 2 )
  3054.         select @orig_db_len = substring( @16data, 38, 2 )
  3055.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3056.         begin 
  3057.             set @originator_id = null 
  3058.             select @originator_id = id from MSrepl_originators where
  3059.                 publisher_database_id = @publisher_database_id 
  3060.                 and UPPER(srvname) = upper(convert(sysname, substring( @16data, 40 + @cmd_data_len, @orig_srv_len )))
  3061.                 and dbname = substring( @16data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3062.             if @originator_id is null
  3063.             begin
  3064.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3065.                     (@publisher_database_id, substring( @16data, 40 + @cmd_data_len, @orig_srv_len ), substring( @16data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3066.                 select @originator_id = @@identity
  3067.             end
  3068.         end
  3069.         else
  3070.             select @originator_id = 0
  3071.  
  3072.         -- Now insert into MSrepl_commands
  3073.  
  3074.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3075.             substring(@16data,11 ,8),
  3076.             substring(@16data,29 ,4), 
  3077.             substring(@16data,21 ,4), 
  3078.             @originator_id, 
  3079.             substring(@16data,25 ,4), 
  3080.             convert(bit,substring(@16data,33 ,1)), 
  3081.             substring(@16data,40,@cmd_data_len) )
  3082.     end
  3083.  
  3084.  
  3085.     IF @17data is null
  3086.       return
  3087.     IF datalength( @17data ) > 39
  3088.     begin
  3089.         -- Get the originator_id for the first command 
  3090.         select @cmd_data_len = substring( @17data, 34, 2 )
  3091.         select @orig_srv_len = substring( @17data, 36, 2 )
  3092.         select @orig_db_len = substring( @17data, 38, 2 )
  3093.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3094.         begin 
  3095.             set @originator_id = null 
  3096.             select @originator_id = id from MSrepl_originators where
  3097.                 publisher_database_id = @publisher_database_id 
  3098.                 and UPPER(srvname) = upper(convert(sysname, substring( @17data, 40 + @cmd_data_len, @orig_srv_len )))
  3099.                 and dbname = substring( @17data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3100.             if @originator_id is null
  3101.             begin
  3102.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3103.                     (@publisher_database_id, substring( @17data, 40 + @cmd_data_len, @orig_srv_len ), substring( @17data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3104.                 select @originator_id = @@identity
  3105.             end
  3106.         end
  3107.         else
  3108.             select @originator_id = 0
  3109.  
  3110.         -- Now insert into MSrepl_commands
  3111.  
  3112.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3113.             substring(@17data,11 ,8),
  3114.             substring(@17data,29 ,4), 
  3115.             substring(@17data,21 ,4), 
  3116.             @originator_id, 
  3117.             substring(@17data,25 ,4), 
  3118.             convert(bit,substring(@17data,33 ,1)), 
  3119.             substring(@17data,40,@cmd_data_len) )
  3120.     end
  3121.  
  3122.  
  3123.     IF @18data is null
  3124.       return
  3125.     IF datalength( @18data ) > 39
  3126.     begin
  3127.         -- Get the originator_id for the first command 
  3128.         select @cmd_data_len = substring( @18data, 34, 2 )
  3129.         select @orig_srv_len = substring( @18data, 36, 2 )
  3130.         select @orig_db_len = substring( @18data, 38, 2 )
  3131.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3132.         begin 
  3133.             set @originator_id = null 
  3134.             select @originator_id = id from MSrepl_originators where
  3135.                 publisher_database_id = @publisher_database_id 
  3136.                 and UPPER(srvname) = upper(convert(sysname, substring( @18data, 40 + @cmd_data_len, @orig_srv_len )))
  3137.                 and dbname = substring( @18data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3138.             if @originator_id is null
  3139.             begin
  3140.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3141.                     (@publisher_database_id, substring( @18data, 40 + @cmd_data_len, @orig_srv_len ), substring( @18data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3142.                 select @originator_id = @@identity
  3143.             end
  3144.         end
  3145.         else
  3146.             select @originator_id = 0
  3147.  
  3148.         -- Now insert into MSrepl_commands
  3149.  
  3150.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3151.             substring(@18data,11 ,8),
  3152.             substring(@18data,29 ,4), 
  3153.             substring(@18data,21 ,4), 
  3154.             @originator_id, 
  3155.             substring(@18data,25 ,4), 
  3156.             convert(bit,substring(@18data,33 ,1)), 
  3157.             substring(@18data,40,@cmd_data_len) )
  3158.     end
  3159.  
  3160.  
  3161.     IF @19data is null
  3162.       return
  3163.     IF datalength( @19data ) > 39
  3164.     begin
  3165.         -- Get the originator_id for the first command 
  3166.         select @cmd_data_len = substring( @19data, 34, 2 )
  3167.         select @orig_srv_len = substring( @19data, 36, 2 )
  3168.         select @orig_db_len = substring( @19data, 38, 2 )
  3169.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3170.         begin 
  3171.             set @originator_id = null 
  3172.             select @originator_id = id from MSrepl_originators where
  3173.                 publisher_database_id = @publisher_database_id 
  3174.                 and UPPER(srvname) = upper(convert(sysname, substring( @19data, 40 + @cmd_data_len, @orig_srv_len )))
  3175.                 and dbname = substring( @19data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3176.             if @originator_id is null
  3177.             begin
  3178.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3179.                     (@publisher_database_id, substring( @19data, 40 + @cmd_data_len, @orig_srv_len ), substring( @19data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3180.                 select @originator_id = @@identity
  3181.             end
  3182.         end
  3183.         else
  3184.             select @originator_id = 0
  3185.  
  3186.         -- Now insert into MSrepl_commands
  3187.  
  3188.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3189.             substring(@19data,11 ,8),
  3190.             substring(@19data,29 ,4), 
  3191.             substring(@19data,21 ,4), 
  3192.             @originator_id, 
  3193.             substring(@19data,25 ,4), 
  3194.             convert(bit,substring(@19data,33 ,1)), 
  3195.             substring(@19data,40,@cmd_data_len) )
  3196.     end
  3197.  
  3198.  
  3199.     IF @20data is null
  3200.       return
  3201.     IF datalength( @20data ) > 39
  3202.     begin
  3203.         -- Get the originator_id for the first command 
  3204.         select @cmd_data_len = substring( @20data, 34, 2 )
  3205.         select @orig_srv_len = substring( @20data, 36, 2 )
  3206.         select @orig_db_len = substring( @20data, 38, 2 )
  3207.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3208.         begin 
  3209.             set @originator_id = null 
  3210.             select @originator_id = id from MSrepl_originators where
  3211.                 publisher_database_id = @publisher_database_id 
  3212.                 and UPPER(srvname) = upper(convert(sysname, substring( @20data, 40 + @cmd_data_len, @orig_srv_len )))
  3213.                 and dbname = substring( @20data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3214.             if @originator_id is null
  3215.             begin
  3216.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3217.                     (@publisher_database_id, substring( @20data, 40 + @cmd_data_len, @orig_srv_len ), substring( @20data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3218.                 select @originator_id = @@identity
  3219.             end
  3220.         end
  3221.         else
  3222.             select @originator_id = 0
  3223.  
  3224.         -- Now insert into MSrepl_commands
  3225.  
  3226.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3227.             substring(@20data,11 ,8),
  3228.             substring(@20data,29 ,4), 
  3229.             substring(@20data,21 ,4), 
  3230.             @originator_id, 
  3231.             substring(@20data,25 ,4), 
  3232.             convert(bit,substring(@20data,33 ,1)), 
  3233.             substring(@20data,40,@cmd_data_len) )
  3234.     end
  3235.  
  3236.     IF @21data is null
  3237.       return
  3238.     IF datalength( @21data ) > 39
  3239.     begin
  3240.         -- Get the originator_id for the first command 
  3241.         select @cmd_data_len = substring( @21data, 34, 2 )
  3242.         select @orig_srv_len = substring( @21data, 36, 2 )
  3243.         select @orig_db_len = substring( @21data, 38, 2 )
  3244.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3245.         begin 
  3246.             set @originator_id = null 
  3247.             select @originator_id = id from MSrepl_originators where
  3248.                 publisher_database_id = @publisher_database_id 
  3249.                 and UPPER(srvname) = upper(convert(sysname, substring( @21data, 40 + @cmd_data_len, @orig_srv_len )))
  3250.                 and dbname = substring( @21data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3251.             if @originator_id is null
  3252.             begin
  3253.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3254.                     (@publisher_database_id, substring( @21data, 40 + @cmd_data_len, @orig_srv_len ), substring( @21data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3255.                 select @originator_id = @@identity
  3256.             end
  3257.         end
  3258.         else
  3259.             select @originator_id = 0
  3260.  
  3261.         -- Now insert into MSrepl_commands
  3262.  
  3263.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3264.             substring(@21data,11 ,8),
  3265.             substring(@21data,29 ,4), 
  3266.             substring(@21data,21 ,4), 
  3267.             @originator_id, 
  3268.             substring(@21data,25 ,4), 
  3269.             convert(bit,substring(@21data,33 ,1)), 
  3270.             substring(@21data,40,@cmd_data_len) )
  3271.     end
  3272.  
  3273.     IF @22data is null
  3274.       return
  3275.     IF datalength( @22data ) > 39
  3276.     begin
  3277.         -- Get the originator_id for the first command 
  3278.         select @cmd_data_len = substring( @22data, 34, 2 )
  3279.         select @orig_srv_len = substring( @22data, 36, 2 )
  3280.         select @orig_db_len = substring( @22data, 38, 2 )
  3281.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3282.         begin 
  3283.             set @originator_id = null 
  3284.             select @originator_id = id from MSrepl_originators where
  3285.                 publisher_database_id = @publisher_database_id 
  3286.                 and UPPER(srvname) = upper(convert(sysname, substring( @22data, 40 + @cmd_data_len, @orig_srv_len )))
  3287.                 and dbname = substring( @22data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3288.             if @originator_id is null
  3289.             begin
  3290.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3291.                     (@publisher_database_id, substring( @22data, 40 + @cmd_data_len, @orig_srv_len ), substring( @22data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3292.                 select @originator_id = @@identity
  3293.             end
  3294.         end
  3295.         else
  3296.             select @originator_id = 0
  3297.  
  3298.         -- Now insert into MSrepl_commands
  3299.  
  3300.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3301.             substring(@22data,11 ,8),
  3302.             substring(@22data,29 ,4), 
  3303.             substring(@22data,21 ,4), 
  3304.             @originator_id, 
  3305.             substring(@22data,25 ,4), 
  3306.             convert(bit,substring(@22data,33 ,1)), 
  3307.             substring(@22data,40,@cmd_data_len) )
  3308.     end
  3309.  
  3310.     IF @23data is null
  3311.       return
  3312.     IF datalength( @23data ) > 39
  3313.     begin
  3314.         -- Get the originator_id for the first command 
  3315.         select @cmd_data_len = substring( @23data, 34, 2 )
  3316.         select @orig_srv_len = substring( @23data, 36, 2 )
  3317.         select @orig_db_len = substring( @23data, 38, 2 )
  3318.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3319.         begin 
  3320.             set @originator_id = null 
  3321.             select @originator_id = id from MSrepl_originators where
  3322.                 publisher_database_id = @publisher_database_id 
  3323.                 and UPPER(srvname) = upper(convert(sysname, substring( @23data, 40 + @cmd_data_len, @orig_srv_len )))
  3324.                 and dbname = substring( @23data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3325.             if @originator_id is null
  3326.             begin
  3327.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3328.                     (@publisher_database_id, substring( @23data, 40 + @cmd_data_len, @orig_srv_len ), substring( @23data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3329.                 select @originator_id = @@identity
  3330.             end
  3331.         end
  3332.         else
  3333.             select @originator_id = 0
  3334.  
  3335.         -- Now insert into MSrepl_commands
  3336.  
  3337.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3338.             substring(@23data,11 ,8),
  3339.             substring(@23data,29 ,4), 
  3340.             substring(@23data,21 ,4), 
  3341.             @originator_id, 
  3342.             substring(@23data,25 ,4), 
  3343.             convert(bit,substring(@23data,33 ,1)), 
  3344.             substring(@23data,40,@cmd_data_len) )
  3345.     end
  3346.  
  3347.     IF @24data is null
  3348.       return
  3349.     IF datalength( @24data ) > 39
  3350.     begin
  3351.         -- Get the originator_id for the first command 
  3352.         select @cmd_data_len = substring( @24data, 34, 2 )
  3353.         select @orig_srv_len = substring( @24data, 36, 2 )
  3354.         select @orig_db_len = substring( @24data, 38, 2 )
  3355.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3356.         begin 
  3357.             set @originator_id = null 
  3358.             select @originator_id = id from MSrepl_originators where
  3359.                 publisher_database_id = @publisher_database_id 
  3360.                 and UPPER(srvname) = upper(convert(sysname, substring( @24data, 40 + @cmd_data_len, @orig_srv_len )))
  3361.                 and dbname = substring( @24data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3362.             if @originator_id is null
  3363.             begin
  3364.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3365.                     (@publisher_database_id, substring( @24data, 40 + @cmd_data_len, @orig_srv_len ), substring( @24data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3366.                 select @originator_id = @@identity
  3367.             end
  3368.         end
  3369.         else
  3370.             select @originator_id = 0
  3371.  
  3372.         -- Now insert into MSrepl_commands
  3373.  
  3374.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3375.             substring(@24data,11 ,8),
  3376.             substring(@24data,29 ,4), 
  3377.             substring(@24data,21 ,4), 
  3378.             @originator_id, 
  3379.             substring(@24data,25 ,4), 
  3380.             convert(bit,substring(@24data,33 ,1)), 
  3381.             substring(@24data,40,@cmd_data_len) )
  3382.     end
  3383.  
  3384.  
  3385.     IF @25data is null
  3386.       return
  3387.     IF datalength( @25data ) > 39
  3388.     begin
  3389.         -- Get the originator_id for the first command 
  3390.         select @cmd_data_len = substring( @25data, 34, 2 )
  3391.         select @orig_srv_len = substring( @25data, 36, 2 )
  3392.         select @orig_db_len = substring( @25data, 38, 2 )
  3393.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3394.         begin 
  3395.             set @originator_id = null 
  3396.             select @originator_id = id from MSrepl_originators where
  3397.                 publisher_database_id = @publisher_database_id 
  3398.                 and UPPER(srvname) = upper(convert(sysname, substring( @25data, 40 + @cmd_data_len, @orig_srv_len )))
  3399.                 and dbname = substring( @25data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3400.             if @originator_id is null
  3401.             begin
  3402.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3403.                     (@publisher_database_id, substring( @25data, 40 + @cmd_data_len, @orig_srv_len ), substring( @25data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3404.                 select @originator_id = @@identity
  3405.             end
  3406.         end
  3407.         else
  3408.             select @originator_id = 0
  3409.  
  3410.         -- Now insert into MSrepl_commands
  3411.  
  3412.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3413.             substring(@25data,11 ,8),
  3414.             substring(@25data,29 ,4), 
  3415.             substring(@25data,21 ,4), 
  3416.             @originator_id, 
  3417.             substring(@25data,25 ,4), 
  3418.             convert(bit,substring(@25data,33 ,1)), 
  3419.             substring(@25data,40,@cmd_data_len) )
  3420.     end
  3421.  
  3422.  
  3423.     IF @26data is null
  3424.       return
  3425.     IF datalength( @26data ) > 39
  3426.     begin
  3427.         -- Get the originator_id for the first command 
  3428.         select @cmd_data_len = substring( @26data, 34, 2 )
  3429.         select @orig_srv_len = substring( @26data, 36, 2 )
  3430.         select @orig_db_len = substring( @26data, 38, 2 )
  3431.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3432.         begin 
  3433.             set @originator_id = null 
  3434.             select @originator_id = id from MSrepl_originators where
  3435.                 publisher_database_id = @publisher_database_id 
  3436.                 and UPPER(srvname) = upper(convert(sysname, substring( @26data, 40 + @cmd_data_len, @orig_srv_len )))
  3437.                 and dbname = substring( @26data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3438.             if @originator_id is null
  3439.             begin
  3440.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3441.                     (@publisher_database_id, substring( @26data, 40 + @cmd_data_len, @orig_srv_len ), substring( @26data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3442.                 select @originator_id = @@identity
  3443.             end
  3444.         end
  3445.         else
  3446.             select @originator_id = 0
  3447.  
  3448.         -- Now insert into MSrepl_commands
  3449.  
  3450.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3451.             substring(@26data,11 ,8),
  3452.             substring(@26data,29 ,4), 
  3453.             substring(@26data,21 ,4), 
  3454.             @originator_id, 
  3455.             substring(@26data,25 ,4), 
  3456.             convert(bit,substring(@26data,33 ,1)), 
  3457.             substring(@26data,40,@cmd_data_len) )
  3458.     end
  3459.  
  3460.  
  3461.     IF @@ERROR <> 0
  3462.       return (1)
  3463. GO
  3464. raiserror(15339,-1,-1,'sp_MSadd_repl_commands27hp')
  3465. GO
  3466. CREATE PROCEDURE sp_MSadd_repl_commands27hp
  3467. @publisher_id smallint,
  3468. @publisher_db sysname,
  3469. @data varbinary( 1575 ),
  3470. @1data varbinary(1575) = NULL,
  3471. @2data varbinary(1575) = NULL,
  3472. @3data varbinary(1575) = NULL,
  3473. @4data varbinary(1575) = NULL,
  3474. @5data varbinary(1575) = NULL,
  3475. @6data varbinary(1575) = NULL,
  3476. @7data varbinary(1575) = NULL,
  3477. @8data varbinary(1575) = NULL,
  3478. @9data varbinary(1575) = NULL,
  3479. @10data varbinary(1575) = NULL,
  3480. @11data varbinary(1575) = NULL,
  3481. @12data varbinary(1575) = NULL,
  3482. @13data varbinary(1575) = NULL,
  3483. @14data varbinary(1575) = NULL,
  3484. @15data varbinary(1575) = NULL,
  3485. @16data varbinary(1575) = NULL,
  3486. @17data varbinary(1575) = NULL,
  3487. @18data varbinary(1575) = NULL,
  3488. @19data varbinary(1575) = NULL,
  3489. @20data varbinary(1575) = NULL,
  3490. @21data varbinary(1575) = NULL,
  3491. @22data varbinary(1575) = NULL,
  3492. @23data varbinary(1575) = NULL,
  3493. @24data varbinary(1575) = NULL,
  3494. @25data varbinary(1575) = NULL,
  3495. @26data varbinary(1575) = NULL
  3496. AS
  3497.  
  3498.     SET NOCOUNT ON
  3499.  
  3500.     DECLARE @xact_id    varbinary(10)
  3501.     DECLARE @xact_seqno varbinary(10)
  3502.     DECLARE @article_id int
  3503.     DECLARE @command_id int
  3504.     DECLARE @type       int
  3505.     DECLARE @partial_command bit
  3506.     DECLARE @command    varbinary(1024)
  3507.  
  3508.     DECLARE @originator sysname
  3509.     DECLARE @originator_db sysname
  3510.  
  3511.     DECLARE @publisher_database_id int
  3512.     DECLARE @date datetime
  3513.     declare @originator_id int
  3514.  
  3515.     DECLARE @cmd_data_len  smallint
  3516.     DECLARE @orig_srv_len smallint
  3517.     DECLARE @orig_db_len  smallint
  3518.  
  3519.     SELECT @date = GETDATE()
  3520.  
  3521.     -- Get publisher database id.
  3522.     SELECT @publisher_database_id = id from MSpublisher_databases where publisher_id = @publisher_id and 
  3523.         publisher_db = @publisher_db
  3524.  
  3525.     -- First insert into MS_repl_transactions
  3526.     IF convert( int, substring( @data, 25, 4 ) ) = 1
  3527.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3528.          substring( @data, 1, 10 ), substring( @data, 11, 10 ), @date)
  3529.  
  3530.     IF @1data is null
  3531.       goto INSERT_CMDS
  3532.     IF convert( int, substring( @1data, 25, 4 ) ) = 1
  3533.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3534.          substring( @1data, 1, 10 ), substring( @1data, 11, 10 ), @date)
  3535.  
  3536.     IF @2data is null
  3537.       goto INSERT_CMDS
  3538.     IF convert( int, substring( @2data, 25, 4 ) ) = 1
  3539.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3540.          substring( @2data, 1, 10 ), substring( @2data, 11, 10 ), @date)
  3541.     
  3542.     IF @3data is null
  3543.       goto INSERT_CMDS
  3544.     IF convert( int, substring( @3data, 25, 4 ) ) = 1
  3545.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3546.          substring( @3data, 1, 10 ), substring( @3data, 11, 10 ), @date)
  3547.  
  3548.     IF @4data is null
  3549.       goto INSERT_CMDS
  3550.     IF convert( int, substring( @4data, 25, 4 ) ) = 1
  3551.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3552.          substring( @4data, 1, 10 ), substring( @4data, 11, 10 ), @date)
  3553.  
  3554.     IF @5data is null
  3555.       goto INSERT_CMDS
  3556.     IF convert( int, substring( @5data, 25, 4 ) ) = 1
  3557.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3558.          substring( @5data, 1, 10 ), substring( @5data, 11, 10 ), @date)
  3559.  
  3560.     IF @6data is null
  3561.       goto INSERT_CMDS
  3562.     IF convert( int, substring( @6data, 25, 4 ) ) = 1
  3563.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3564.          substring( @6data, 1, 10 ), substring( @6data, 11, 10 ), @date)
  3565.  
  3566.     IF @7data is null
  3567.       goto INSERT_CMDS
  3568.     IF convert( int, substring( @7data, 25, 4 ) ) = 1
  3569.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3570.          substring( @7data, 1, 10 ), substring( @7data, 11, 10 ), @date)
  3571.  
  3572.     IF @8data is null
  3573.       goto INSERT_CMDS
  3574.     IF convert( int, substring( @8data, 25, 4 ) ) = 1
  3575.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3576.          substring( @8data, 1, 10 ), substring( @8data, 11, 10 ), @date)
  3577.  
  3578.     IF @9data is null
  3579.       goto INSERT_CMDS
  3580.     IF convert( int, substring( @9data, 25, 4 ) ) = 1
  3581.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3582.          substring( @9data, 1, 10 ), substring( @9data, 11, 10 ), @date)
  3583.  
  3584.     IF @10data is null
  3585.       goto INSERT_CMDS
  3586.     IF convert( int, substring( @10data, 25, 4 ) ) = 1
  3587.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3588.          substring( @10data, 1, 10 ), substring( @10data, 11, 10 ), @date)
  3589.  
  3590.     IF @11data is null
  3591.       goto INSERT_CMDS
  3592.     IF convert( int, substring( @11data, 25, 4 ) ) = 1
  3593.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3594.          substring( @11data, 1, 10 ), substring( @11data, 11, 10 ), @date)
  3595.  
  3596.     IF @12data is null
  3597.       goto INSERT_CMDS
  3598.     IF convert( int, substring( @12data, 25, 4 ) ) = 1
  3599.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3600.          substring( @12data, 1, 10 ), substring( @12data, 11, 10 ), @date)
  3601.  
  3602.     IF @13data is null
  3603.       goto INSERT_CMDS
  3604.     IF convert( int, substring( @13data, 25, 4 ) ) = 1
  3605.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3606.          substring( @13data, 1, 10 ), substring( @13data, 11, 10 ), @date)
  3607.  
  3608.     IF @14data is null
  3609.       goto INSERT_CMDS
  3610.     IF convert( int, substring( @14data, 25, 4 ) ) = 1
  3611.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3612.          substring( @14data, 1, 10 ), substring( @14data, 11, 10 ), @date)
  3613.  
  3614.     IF @15data is null
  3615.       goto INSERT_CMDS
  3616.     IF convert( int, substring( @15data, 25, 4 ) ) = 1
  3617.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3618.          substring( @15data, 1, 10 ), substring( @15data, 11, 10 ), @date)
  3619.  
  3620.     IF @16data is null
  3621.       goto INSERT_CMDS
  3622.     IF convert( int, substring( @16data, 25, 4 ) ) = 1
  3623.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3624.          substring( @16data, 1, 10 ), substring( @16data, 11, 10 ), @date)
  3625.  
  3626.     IF @17data is null
  3627.       goto INSERT_CMDS
  3628.     IF convert( int, substring( @17data, 25, 4 ) ) = 1
  3629.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3630.          substring( @17data, 1, 10 ), substring( @17data, 11, 10 ), @date)
  3631.  
  3632.     IF @18data is null
  3633.       goto INSERT_CMDS
  3634.     IF convert( int, substring( @18data, 25, 4 ) ) = 1
  3635.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3636.          substring( @18data, 1, 10 ), substring( @18data, 11, 10 ), @date)
  3637.  
  3638.     IF @19data is null
  3639.       goto INSERT_CMDS
  3640.     IF convert( int, substring( @19data, 25, 4 ) ) = 1
  3641.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3642.          substring( @19data, 1, 10 ), substring( @19data, 11, 10 ), @date)
  3643.  
  3644.     IF @20data is null
  3645.       goto INSERT_CMDS
  3646.     IF convert( int, substring( @20data, 25, 4 ) ) = 1
  3647.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3648.          substring( @20data, 1, 10 ), substring( @20data, 11, 10 ), @date)
  3649.  
  3650.     IF @21data is null
  3651.       goto INSERT_CMDS
  3652.     IF convert( int, substring( @21data, 25, 4 ) ) = 1
  3653.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3654.          substring( @21data, 1, 10 ), substring( @21data, 11, 10 ), @date)
  3655.  
  3656.     IF @22data is null
  3657.       goto INSERT_CMDS
  3658.     IF convert( int, substring( @22data, 25, 4 ) ) = 1
  3659.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3660.          substring( @22data, 1, 10 ), substring( @22data, 11, 10 ), @date)
  3661.  
  3662.     IF @23data is null
  3663.       goto INSERT_CMDS
  3664.     IF convert( int, substring( @23data, 25, 4 ) ) = 1
  3665.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3666.          substring( @23data, 1, 10 ), substring( @23data, 11, 10 ), @date)
  3667.  
  3668.     IF @24data is null
  3669.       goto INSERT_CMDS
  3670.     IF convert( int, substring( @24data, 25, 4 ) ) = 1
  3671.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3672.          substring( @24data, 1, 10 ), substring( @24data, 11, 10 ), @date)
  3673.  
  3674.     IF @25data is null
  3675.       goto INSERT_CMDS
  3676.     IF convert( int, substring( @25data, 25, 4 ) ) = 1
  3677.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3678.          substring( @25data, 1, 10 ), substring( @25data, 11, 10 ), @date)
  3679.  
  3680.     IF @26data is null
  3681.       goto INSERT_CMDS
  3682.     IF convert( int, substring( @26data, 25, 4 ) ) = 1
  3683.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3684.          substring( @26data, 1, 10 ), substring( @26data, 11, 10 ), @date)
  3685.  
  3686. INSERT_CMDS:
  3687.  
  3688.     if datalength( @data ) > 39
  3689.     begin
  3690.         -- Get the originator_id for the first command 
  3691.         select @cmd_data_len = substring( @data, 34, 2 )
  3692.         select @orig_srv_len = substring( @data, 36, 2 )
  3693.         select @orig_db_len = substring( @data, 38, 2 )
  3694.  
  3695.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3696.         begin 
  3697.             set @originator_id = null 
  3698.             select @originator_id = id from MSrepl_originators where
  3699.                 publisher_database_id = @publisher_database_id 
  3700.                 and UPPER(srvname) = upper(convert(sysname, substring( @data, 40 + @cmd_data_len, @orig_srv_len )))
  3701.                 and dbname = substring( @data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3702.             if @originator_id is null
  3703.             begin
  3704.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3705.                     (@publisher_database_id, substring( @data, 40 + @cmd_data_len, @orig_srv_len ), substring( @data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3706.                 select @originator_id = @@identity
  3707.             end
  3708.         end
  3709.         else
  3710.             select @originator_id = 0
  3711.  
  3712.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3713.             substring(@data,11,10),
  3714.             substring(@data,29,4), 
  3715.             substring(@data,21,4), 
  3716.             @originator_id, 
  3717.             substring(@data,25,4), 
  3718.             convert(bit,substring(@data,33,1)), 
  3719.             substring(@data,40,@cmd_data_len) )
  3720.     end
  3721.     
  3722.     IF @1data is null
  3723.       return
  3724.     IF datalength( @1data ) > 39
  3725.     begin
  3726.         -- Get the originator_id for the first command 
  3727.         select @cmd_data_len = substring( @1data, 34, 2 )
  3728.         select @orig_srv_len = substring( @1data, 36, 2 )
  3729.         select @orig_db_len = substring( @1data, 38, 2 )
  3730.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3731.         begin 
  3732.             set @originator_id = null 
  3733.             select @originator_id = id from MSrepl_originators where
  3734.                 publisher_database_id = @publisher_database_id 
  3735.                 and UPPER(srvname) = upper(convert(sysname, substring( @1data, 40 + @cmd_data_len, @orig_srv_len )))
  3736.                 and dbname = substring( @1data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3737.             if @originator_id is null
  3738.             begin
  3739.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3740.                     (@publisher_database_id, substring( @1data, 40 + @cmd_data_len, @orig_srv_len ), substring( @1data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3741.                 select @originator_id = @@identity
  3742.             end
  3743.         end
  3744.         else
  3745.             select @originator_id = 0
  3746.  
  3747.         -- Now insert into MSrepl_commands
  3748.  
  3749.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3750.             substring(@1data,11,10),
  3751.             substring(@1data,29,4), 
  3752.             substring(@1data,21,4), 
  3753.             @originator_id, 
  3754.             substring(@1data,25,4), 
  3755.             convert(bit,substring(@1data,33,1)), 
  3756.             substring(@1data,40,@cmd_data_len) )
  3757.     end
  3758.  
  3759.     IF @2data is null
  3760.       return
  3761.     IF datalength( @2data ) > 39
  3762.     begin
  3763.         -- Get the originator_id for the first command 
  3764.         select @cmd_data_len = substring( @2data, 34, 2 )
  3765.         select @orig_srv_len = substring( @2data, 36, 2 )
  3766.         select @orig_db_len = substring( @2data, 38, 2 )
  3767.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3768.         begin 
  3769.             set @originator_id = null 
  3770.             select @originator_id = id from MSrepl_originators where
  3771.                 publisher_database_id = @publisher_database_id 
  3772.                 and UPPER(srvname) = upper(convert(sysname, substring( @2data, 40 + @cmd_data_len, @orig_srv_len )))
  3773.                 and dbname = substring( @2data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3774.             if @originator_id is null
  3775.             begin
  3776.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3777.                     (@publisher_database_id, substring( @2data, 40 + @cmd_data_len, @orig_srv_len ), substring( @2data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3778.                 select @originator_id = @@identity
  3779.             end
  3780.         end
  3781.         else
  3782.             select @originator_id = 0
  3783.  
  3784.         -- Now insert into MSrepl_commands
  3785.  
  3786.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3787.             substring(@2data,11 ,10),
  3788.             substring(@2data,29 ,4), 
  3789.             substring(@2data,21 ,4), 
  3790.             @originator_id, 
  3791.             substring(@2data,25 ,4), 
  3792.             convert(bit,substring(@2data,33 ,1)), 
  3793.             substring(@2data,40,@cmd_data_len) )
  3794.     end
  3795.  
  3796.     IF @3data is null
  3797.       return
  3798.     IF datalength( @3data ) > 39
  3799.     begin
  3800.         -- Get the originator_id for the first command 
  3801.         select @cmd_data_len = substring( @3data, 34, 2 )
  3802.         select @orig_srv_len = substring( @3data, 36, 2 )
  3803.         select @orig_db_len = substring( @3data, 38, 2 )
  3804.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3805.         begin 
  3806.             set @originator_id = null 
  3807.             select @originator_id = id from MSrepl_originators where
  3808.                 publisher_database_id = @publisher_database_id 
  3809.                 and UPPER(srvname) = upper(convert(sysname, substring( @3data, 40 + @cmd_data_len, @orig_srv_len )))
  3810.                 and dbname = substring( @3data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3811.             if @originator_id is null
  3812.             begin
  3813.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3814.                     (@publisher_database_id, substring( @3data, 40 + @cmd_data_len, @orig_srv_len ), substring( @3data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3815.                 select @originator_id = @@identity
  3816.             end
  3817.         end
  3818.         else
  3819.             select @originator_id = 0
  3820.  
  3821.         -- Now insert into MSrepl_commands
  3822.  
  3823.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3824.             substring(@3data,11 ,10),
  3825.             substring(@3data,29 ,4), 
  3826.             substring(@3data,21 ,4), 
  3827.             @originator_id, 
  3828.             substring(@3data,25 ,4), 
  3829.             convert(bit,substring(@3data,33 ,1)), 
  3830.             substring(@3data,40,@cmd_data_len) )
  3831.     end
  3832.  
  3833.     IF @4data is null
  3834.       return
  3835.     IF datalength( @4data ) > 39
  3836.     begin
  3837.         -- Get the originator_id for the first command 
  3838.         select @cmd_data_len = substring( @4data, 34, 2 )
  3839.         select @orig_srv_len = substring( @4data, 36, 2 )
  3840.         select @orig_db_len = substring( @4data, 38, 2 )
  3841.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3842.         begin 
  3843.             set @originator_id = null 
  3844.             select @originator_id = id from MSrepl_originators where
  3845.                 publisher_database_id = @publisher_database_id 
  3846.                 and UPPER(srvname) = upper(convert(sysname, substring( @4data, 40 + @cmd_data_len, @orig_srv_len )))
  3847.                 and dbname = substring( @4data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3848.             if @originator_id is null
  3849.             begin
  3850.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3851.                     (@publisher_database_id, substring( @4data, 40 + @cmd_data_len, @orig_srv_len ), substring( @4data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3852.                 select @originator_id = @@identity
  3853.             end
  3854.         end
  3855.         else
  3856.             select @originator_id = 0
  3857.  
  3858.         -- Now insert into MSrepl_commands
  3859.  
  3860.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3861.             substring(@4data,11 ,10),
  3862.             substring(@4data,29 ,4), 
  3863.             substring(@4data,21 ,4), 
  3864.             @originator_id, 
  3865.             substring(@4data,25 ,4), 
  3866.             convert(bit,substring(@4data,33 ,1)), 
  3867.             substring(@4data,40,@cmd_data_len) )
  3868.     end
  3869.  
  3870.     IF @5data is null
  3871.       return
  3872.     IF datalength( @5data ) > 39
  3873.     begin
  3874.         -- Get the originator_id for the first command 
  3875.         select @cmd_data_len = substring( @5data, 34, 2 )
  3876.         select @orig_srv_len = substring( @5data, 36, 2 )
  3877.         select @orig_db_len = substring( @5data, 38, 2 )
  3878.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3879.         begin 
  3880.             set @originator_id = null 
  3881.             select @originator_id = id from MSrepl_originators where
  3882.                 publisher_database_id = @publisher_database_id 
  3883.                 and UPPER(srvname) = upper(convert(sysname, substring( @5data, 40 + @cmd_data_len, @orig_srv_len )))
  3884.                 and dbname = substring( @5data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3885.             if @originator_id is null
  3886.             begin
  3887.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3888.                     (@publisher_database_id, substring( @5data, 40 + @cmd_data_len, @orig_srv_len ), substring( @5data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3889.                 select @originator_id = @@identity
  3890.             end
  3891.         end
  3892.         else
  3893.             select @originator_id = 0
  3894.  
  3895.         -- Now insert into MSrepl_commands
  3896.  
  3897.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3898.             substring(@5data,11 ,10),
  3899.             substring(@5data,29 ,4), 
  3900.             substring(@5data,21 ,4), 
  3901.             @originator_id, 
  3902.             substring(@5data,25 ,4), 
  3903.             convert(bit,substring(@5data,33 ,1)), 
  3904.             substring(@5data,40,@cmd_data_len) )
  3905.     end
  3906.  
  3907.     IF @6data is null
  3908.       return
  3909.     IF datalength( @6data ) > 39
  3910.     begin
  3911.         -- Get the originator_id for the first command 
  3912.         select @cmd_data_len = substring( @6data, 34, 2 )
  3913.         select @orig_srv_len = substring( @6data, 36, 2 )
  3914.         select @orig_db_len = substring( @6data, 38, 2 )
  3915.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3916.         begin 
  3917.             set @originator_id = null 
  3918.             select @originator_id = id from MSrepl_originators where
  3919.                 publisher_database_id = @publisher_database_id 
  3920.                 and UPPER(srvname) = upper(convert(sysname, substring( @6data, 40 + @cmd_data_len, @orig_srv_len )))
  3921.                 and dbname = substring( @6data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3922.             if @originator_id is null
  3923.             begin
  3924.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3925.                     (@publisher_database_id, substring( @6data, 40 + @cmd_data_len, @orig_srv_len ), substring( @6data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3926.                 select @originator_id = @@identity
  3927.             end
  3928.         end
  3929.         else
  3930.             select @originator_id = 0
  3931.  
  3932.         -- Now insert into MSrepl_commands
  3933.  
  3934.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3935.             substring(@6data,11 ,10),
  3936.             substring(@6data,29 ,4), 
  3937.             substring(@6data,21 ,4), 
  3938.             @originator_id, 
  3939.             substring(@6data,25 ,4), 
  3940.             convert(bit,substring(@6data,33 ,1)), 
  3941.             substring(@6data,40,@cmd_data_len) )
  3942.     end
  3943.  
  3944.     IF @7data is null
  3945.       return
  3946.     IF datalength( @7data ) > 39
  3947.     begin
  3948.         -- Get the originator_id for the first command 
  3949.         select @cmd_data_len = substring( @7data, 34, 2 )
  3950.         select @orig_srv_len = substring( @7data, 36, 2 )
  3951.         select @orig_db_len = substring( @7data, 38, 2 )
  3952.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3953.         begin 
  3954.             set @originator_id = null 
  3955.             select @originator_id = id from MSrepl_originators where
  3956.                 publisher_database_id = @publisher_database_id 
  3957.                 and UPPER(srvname) = upper(convert(sysname, substring( @7data, 40 + @cmd_data_len, @orig_srv_len )))
  3958.                 and dbname = substring( @7data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3959.             if @originator_id is null
  3960.             begin
  3961.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3962.                     (@publisher_database_id, substring( @7data, 40 + @cmd_data_len, @orig_srv_len ), substring( @7data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3963.                 select @originator_id = @@identity
  3964.             end
  3965.         end
  3966.         else
  3967.             select @originator_id = 0
  3968.  
  3969.         -- Now insert into MSrepl_commands
  3970.  
  3971.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3972.             substring(@7data,11 ,10),
  3973.             substring(@7data,29 ,4), 
  3974.             substring(@7data,21 ,4), 
  3975.             @originator_id, 
  3976.             substring(@7data,25 ,4), 
  3977.             convert(bit,substring(@7data,33 ,1)), 
  3978.             substring(@7data,40,@cmd_data_len) )
  3979.     end
  3980.  
  3981.     IF @8data is null
  3982.       return
  3983.     IF datalength( @8data ) > 39
  3984.     begin
  3985.         -- Get the originator_id for the first command 
  3986.         select @cmd_data_len = substring( @8data, 34, 2 )
  3987.         select @orig_srv_len = substring( @8data, 36, 2 )
  3988.         select @orig_db_len = substring( @8data, 38, 2 )
  3989.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3990.         begin 
  3991.             set @originator_id = null 
  3992.             select @originator_id = id from MSrepl_originators where
  3993.                 publisher_database_id = @publisher_database_id 
  3994.                 and UPPER(srvname) = upper(convert(sysname, substring( @8data, 40 + @cmd_data_len, @orig_srv_len )))
  3995.                 and dbname = substring( @8data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3996.             if @originator_id is null
  3997.             begin
  3998.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3999.                     (@publisher_database_id, substring( @8data, 40 + @cmd_data_len, @orig_srv_len ), substring( @8data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4000.                 select @originator_id = @@identity
  4001.             end
  4002.         end
  4003.         else
  4004.             select @originator_id = 0
  4005.  
  4006.         -- Now insert into MSrepl_commands
  4007.  
  4008.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4009.             substring(@8data,11 ,10),
  4010.             substring(@8data,29 ,4), 
  4011.             substring(@8data,21 ,4), 
  4012.             @originator_id, 
  4013.             substring(@8data,25 ,4), 
  4014.             convert(bit,substring(@8data,33 ,1)), 
  4015.             substring(@8data,40,@cmd_data_len) )
  4016.     end
  4017.  
  4018.     IF @9data is null
  4019.       return
  4020.     IF datalength( @9data ) > 39
  4021.     begin
  4022.         -- Get the originator_id for the first command 
  4023.         select @cmd_data_len = substring( @9data, 34, 2 )
  4024.         select @orig_srv_len = substring( @9data, 36, 2 )
  4025.         select @orig_db_len = substring( @9data, 38, 2 )
  4026.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4027.         begin 
  4028.             set @originator_id = null 
  4029.             select @originator_id = id from MSrepl_originators where
  4030.                 publisher_database_id = @publisher_database_id 
  4031.                 and upper(srvname) = upper(convert(sysname, substring( @9data, 40 + @cmd_data_len, @orig_srv_len )))
  4032.                 and dbname = substring( @9data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4033.             if @originator_id is null
  4034.             begin
  4035.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4036.                     (@publisher_database_id, substring( @9data, 40 + @cmd_data_len, @orig_srv_len ), substring( @9data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4037.                 select @originator_id = @@identity
  4038.             end
  4039.         end
  4040.         else
  4041.             select @originator_id = 0
  4042.  
  4043.         -- Now insert into MSrepl_commands
  4044.  
  4045.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4046.             substring(@9data,11 ,10),
  4047.             substring(@9data,29 ,4), 
  4048.             substring(@9data,21 ,4), 
  4049.             @originator_id, 
  4050.             substring(@9data,25 ,4), 
  4051.             convert(bit,substring(@9data,33 ,1)), 
  4052.             substring(@9data,40,@cmd_data_len) )
  4053.     end
  4054.  
  4055.     IF @10data is null
  4056.       return
  4057.     IF datalength( @10data ) > 39
  4058.     begin
  4059.         -- Get the originator_id for the first command 
  4060.         select @cmd_data_len = substring( @10data, 34, 2 )
  4061.         select @orig_srv_len = substring( @10data, 36, 2 )
  4062.         select @orig_db_len = substring( @10data, 38, 2 )
  4063.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4064.         begin 
  4065.             set @originator_id = null 
  4066.             select @originator_id = id from MSrepl_originators where
  4067.                 publisher_database_id = @publisher_database_id 
  4068.                 and UPPER(srvname) = upper(convert(sysname, substring( @10data, 40 + @cmd_data_len, @orig_srv_len )))
  4069.                 and dbname = substring( @10data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4070.             if @originator_id is null
  4071.             begin
  4072.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4073.                     (@publisher_database_id, substring( @10data, 40 + @cmd_data_len, @orig_srv_len ), substring( @10data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4074.                 select @originator_id = @@identity
  4075.             end
  4076.         end
  4077.         else
  4078.             select @originator_id = 0
  4079.  
  4080.         -- Now insert into MSrepl_commands
  4081.  
  4082.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4083.             substring(@10data,11 ,10),
  4084.             substring(@10data,29 ,4), 
  4085.             substring(@10data,21 ,4), 
  4086.             @originator_id, 
  4087.             substring(@10data,25 ,4), 
  4088.             convert(bit,substring(@10data,33 ,1)), 
  4089.             substring(@10data,40,@cmd_data_len) )
  4090.     end
  4091.  
  4092.     IF @11data is null
  4093.       return
  4094.     IF datalength( @11data ) > 39
  4095.     begin
  4096.         -- Get the originator_id for the first command 
  4097.         select @cmd_data_len = substring( @11data, 34, 2 )
  4098.         select @orig_srv_len = substring( @11data, 36, 2 )
  4099.         select @orig_db_len = substring( @11data, 38, 2 )
  4100.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4101.         begin 
  4102.             set @originator_id = null 
  4103.             select @originator_id = id from MSrepl_originators where
  4104.                 publisher_database_id = @publisher_database_id 
  4105.                 and UPPER(srvname) = upper(convert(sysname, substring( @11data, 40 + @cmd_data_len, @orig_srv_len )))
  4106.                 and dbname = substring( @11data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4107.             if @originator_id is null
  4108.             begin
  4109.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4110.                     (@publisher_database_id, substring( @11data, 40 + @cmd_data_len, @orig_srv_len ), substring( @11data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4111.                 select @originator_id = @@identity
  4112.             end
  4113.         end
  4114.         else
  4115.             select @originator_id = 0
  4116.  
  4117.         -- Now insert into MSrepl_commands
  4118.  
  4119.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4120.             substring(@11data,11 ,10),
  4121.             substring(@11data,29 ,4), 
  4122.             substring(@11data,21 ,4), 
  4123.             @originator_id, 
  4124.             substring(@11data,25 ,4), 
  4125.             convert(bit,substring(@11data,33 ,1)), 
  4126.             substring(@11data,40,@cmd_data_len) )
  4127.     end
  4128.  
  4129.     IF @12data is null
  4130.       return
  4131.     IF datalength( @12data ) > 39
  4132.     begin
  4133.         -- Get the originator_id for the first command 
  4134.         select @cmd_data_len = substring( @12data, 34, 2 )
  4135.         select @orig_srv_len = substring( @12data, 36, 2 )
  4136.         select @orig_db_len = substring( @12data, 38, 2 )
  4137.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4138.         begin 
  4139.             set @originator_id = null 
  4140.             select @originator_id = id from MSrepl_originators where
  4141.                 publisher_database_id = @publisher_database_id 
  4142.                 and UPPER(srvname) = upper(convert(sysname, substring( @12data, 40 + @cmd_data_len, @orig_srv_len )))
  4143.                 and dbname = substring( @12data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4144.             if @originator_id is null
  4145.             begin
  4146.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4147.                     (@publisher_database_id, substring( @12data, 40 + @cmd_data_len, @orig_srv_len ), substring( @12data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4148.                 select @originator_id = @@identity
  4149.             end
  4150.         end
  4151.         else
  4152.             select @originator_id = 0
  4153.  
  4154.         -- Now insert into MSrepl_commands
  4155.  
  4156.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4157.             substring(@12data,11 ,10),
  4158.             substring(@12data,29 ,4), 
  4159.             substring(@12data,21 ,4), 
  4160.             @originator_id, 
  4161.             substring(@12data,25 ,4), 
  4162.             convert(bit,substring(@12data,33 ,1)), 
  4163.             substring(@12data,40,@cmd_data_len) )
  4164.     end
  4165.  
  4166.  
  4167.     IF @13data is null
  4168.       return
  4169.     IF datalength( @13data ) > 39
  4170.     begin
  4171.         -- Get the originator_id for the first command 
  4172.         select @cmd_data_len = substring( @13data, 34, 2 )
  4173.         select @orig_srv_len = substring( @13data, 36, 2 )
  4174.         select @orig_db_len = substring( @13data, 38, 2 )
  4175.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4176.         begin 
  4177.             set @originator_id = null 
  4178.             select @originator_id = id from MSrepl_originators where
  4179.                 publisher_database_id = @publisher_database_id 
  4180.                 and UPPER(srvname) = upper(convert(sysname, substring( @13data, 40 + @cmd_data_len, @orig_srv_len )))
  4181.                 and dbname = substring( @13data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4182.             if @originator_id is null
  4183.             begin
  4184.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4185.                     (@publisher_database_id, substring( @13data, 40 + @cmd_data_len, @orig_srv_len ), substring( @13data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4186.                 select @originator_id = @@identity
  4187.             end
  4188.         end
  4189.         else
  4190.             select @originator_id = 0
  4191.  
  4192.         -- Now insert into MSrepl_commands
  4193.  
  4194.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4195.             substring(@13data,11 ,10),
  4196.             substring(@13data,29 ,4), 
  4197.             substring(@13data,21 ,4), 
  4198.             @originator_id, 
  4199.             substring(@13data,25 ,4), 
  4200.             convert(bit,substring(@13data,33 ,1)), 
  4201.             substring(@13data,40,@cmd_data_len) )
  4202.     end
  4203.  
  4204.     IF @14data is null
  4205.       return
  4206.     IF datalength( @14data ) > 39
  4207.     begin
  4208.         -- Get the originator_id for the first command 
  4209.         select @cmd_data_len = substring( @14data, 34, 2 )
  4210.         select @orig_srv_len = substring( @14data, 36, 2 )
  4211.         select @orig_db_len = substring( @14data, 38, 2 )
  4212.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4213.         begin 
  4214.             set @originator_id = null 
  4215.             select @originator_id = id from MSrepl_originators where
  4216.                 publisher_database_id = @publisher_database_id 
  4217.                 and UPPER(srvname) = upper(convert(sysname, substring( @14data, 40 + @cmd_data_len, @orig_srv_len )))
  4218.                 and dbname = substring( @14data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4219.             if @originator_id is null
  4220.             begin
  4221.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4222.                     (@publisher_database_id, substring( @14data, 40 + @cmd_data_len, @orig_srv_len ), substring( @14data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4223.                 select @originator_id = @@identity
  4224.             end
  4225.         end
  4226.         else
  4227.             select @originator_id = 0
  4228.  
  4229.         -- Now insert into MSrepl_commands
  4230.  
  4231.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4232.             substring(@14data,11 ,10),
  4233.             substring(@14data,29 ,4), 
  4234.             substring(@14data,21 ,4), 
  4235.             @originator_id, 
  4236.             substring(@14data,25 ,4), 
  4237.             convert(bit,substring(@14data,33 ,1)), 
  4238.             substring(@14data,40,@cmd_data_len) )
  4239.     end
  4240.  
  4241.  
  4242.     IF @15data is null
  4243.       return
  4244.     IF datalength( @15data ) > 39
  4245.     begin
  4246.         -- Get the originator_id for the first command 
  4247.         select @cmd_data_len = substring( @15data, 34, 2 )
  4248.         select @orig_srv_len = substring( @15data, 36, 2 )
  4249.         select @orig_db_len = substring( @15data, 38, 2 )
  4250.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4251.         begin 
  4252.             set @originator_id = null 
  4253.             select @originator_id = id from MSrepl_originators where
  4254.                 publisher_database_id = @publisher_database_id 
  4255.                 and UPPER(srvname) = upper(convert(sysname, substring( @15data, 40 + @cmd_data_len, @orig_srv_len )))
  4256.                 and dbname = substring( @15data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4257.             if @originator_id is null
  4258.             begin
  4259.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4260.                     (@publisher_database_id, substring( @15data, 40 + @cmd_data_len, @orig_srv_len ), substring( @15data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4261.                 select @originator_id = @@identity
  4262.             end
  4263.         end
  4264.         else
  4265.             select @originator_id = 0
  4266.  
  4267.         -- Now insert into MSrepl_commands
  4268.  
  4269.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4270.             substring(@15data,11 ,10),
  4271.             substring(@15data,29 ,4), 
  4272.             substring(@15data,21 ,4), 
  4273.             @originator_id, 
  4274.             substring(@15data,25 ,4), 
  4275.             convert(bit,substring(@15data,33 ,1)), 
  4276.             substring(@15data,40,@cmd_data_len) )
  4277.     end
  4278.  
  4279.     IF @16data is null
  4280.       return
  4281.     IF datalength( @16data ) > 39
  4282.     begin
  4283.         -- Get the originator_id for the first command 
  4284.         select @cmd_data_len = substring( @16data, 34, 2 )
  4285.         select @orig_srv_len = substring( @16data, 36, 2 )
  4286.         select @orig_db_len = substring( @16data, 38, 2 )
  4287.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4288.         begin 
  4289.             set @originator_id = null 
  4290.             select @originator_id = id from MSrepl_originators where
  4291.                 publisher_database_id = @publisher_database_id 
  4292.                 and UPPER(srvname) = upper(convert(sysname, substring( @16data, 40 + @cmd_data_len, @orig_srv_len )))
  4293.                 and dbname = substring( @16data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4294.             if @originator_id is null
  4295.             begin
  4296.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4297.                     (@publisher_database_id, substring( @16data, 40 + @cmd_data_len, @orig_srv_len ), substring( @16data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4298.                 select @originator_id = @@identity
  4299.             end
  4300.         end
  4301.         else
  4302.             select @originator_id = 0
  4303.  
  4304.         -- Now insert into MSrepl_commands
  4305.  
  4306.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4307.             substring(@16data,11 ,10),
  4308.             substring(@16data,29 ,4), 
  4309.             substring(@16data,21 ,4), 
  4310.             @originator_id, 
  4311.             substring(@16data,25 ,4), 
  4312.             convert(bit,substring(@16data,33 ,1)), 
  4313.             substring(@16data,40,@cmd_data_len) )
  4314.     end
  4315.  
  4316.  
  4317.     IF @17data is null
  4318.       return
  4319.     IF datalength( @17data ) > 39
  4320.     begin
  4321.         -- Get the originator_id for the first command 
  4322.         select @cmd_data_len = substring( @17data, 34, 2 )
  4323.         select @orig_srv_len = substring( @17data, 36, 2 )
  4324.         select @orig_db_len = substring( @17data, 38, 2 )
  4325.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4326.         begin 
  4327.             set @originator_id = null 
  4328.             select @originator_id = id from MSrepl_originators where
  4329.                 publisher_database_id = @publisher_database_id 
  4330.                 and UPPER(srvname) = upper(convert(sysname, substring( @17data, 40 + @cmd_data_len, @orig_srv_len )))
  4331.                 and dbname = substring( @17data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4332.             if @originator_id is null
  4333.             begin
  4334.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4335.                     (@publisher_database_id, substring( @17data, 40 + @cmd_data_len, @orig_srv_len ), substring( @17data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4336.                 select @originator_id = @@identity
  4337.             end
  4338.         end
  4339.         else
  4340.             select @originator_id = 0
  4341.  
  4342.         -- Now insert into MSrepl_commands
  4343.  
  4344.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4345.             substring(@17data,11 ,10),
  4346.             substring(@17data,29 ,4), 
  4347.             substring(@17data,21 ,4), 
  4348.             @originator_id, 
  4349.             substring(@17data,25 ,4), 
  4350.             convert(bit,substring(@17data,33 ,1)), 
  4351.             substring(@17data,40,@cmd_data_len) )
  4352.     end
  4353.  
  4354.  
  4355.     IF @18data is null
  4356.       return
  4357.     IF datalength( @18data ) > 39
  4358.     begin
  4359.         -- Get the originator_id for the first command 
  4360.         select @cmd_data_len = substring( @18data, 34, 2 )
  4361.         select @orig_srv_len = substring( @18data, 36, 2 )
  4362.         select @orig_db_len = substring( @18data, 38, 2 )
  4363.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4364.         begin 
  4365.             set @originator_id = null 
  4366.             select @originator_id = id from MSrepl_originators where
  4367.                 publisher_database_id = @publisher_database_id 
  4368.                 and UPPER(srvname) = upper(convert(sysname, substring( @18data, 40 + @cmd_data_len, @orig_srv_len )))
  4369.                 and dbname = substring( @18data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4370.             if @originator_id is null
  4371.             begin
  4372.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4373.                     (@publisher_database_id, substring( @18data, 40 + @cmd_data_len, @orig_srv_len ), substring( @18data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4374.                 select @originator_id = @@identity
  4375.             end
  4376.         end
  4377.         else
  4378.             select @originator_id = 0
  4379.  
  4380.         -- Now insert into MSrepl_commands
  4381.  
  4382.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4383.             substring(@18data,11 ,10),
  4384.             substring(@18data,29 ,4), 
  4385.             substring(@18data,21 ,4), 
  4386.             @originator_id, 
  4387.             substring(@18data,25 ,4), 
  4388.             convert(bit,substring(@18data,33 ,1)), 
  4389.             substring(@18data,40,@cmd_data_len) )
  4390.     end
  4391.  
  4392.  
  4393.     IF @19data is null
  4394.       return
  4395.     IF datalength( @19data ) > 39
  4396.     begin
  4397.         -- Get the originator_id for the first command 
  4398.         select @cmd_data_len = substring( @19data, 34, 2 )
  4399.         select @orig_srv_len = substring( @19data, 36, 2 )
  4400.         select @orig_db_len = substring( @19data, 38, 2 )
  4401.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4402.         begin 
  4403.             set @originator_id = null 
  4404.             select @originator_id = id from MSrepl_originators where
  4405.                 publisher_database_id = @publisher_database_id 
  4406.                 and UPPER(srvname) = upper(convert(sysname, substring( @19data, 40 + @cmd_data_len, @orig_srv_len )))
  4407.                 and dbname = substring( @19data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4408.             if @originator_id is null
  4409.             begin
  4410.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4411.                     (@publisher_database_id, substring( @19data, 40 + @cmd_data_len, @orig_srv_len ), substring( @19data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4412.                 select @originator_id = @@identity
  4413.             end
  4414.         end
  4415.         else
  4416.             select @originator_id = 0
  4417.  
  4418.         -- Now insert into MSrepl_commands
  4419.  
  4420.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4421.             substring(@19data,11 ,10),
  4422.             substring(@19data,29 ,4), 
  4423.             substring(@19data,21 ,4), 
  4424.             @originator_id, 
  4425.             substring(@19data,25 ,4), 
  4426.             convert(bit,substring(@19data,33 ,1)), 
  4427.             substring(@19data,40,@cmd_data_len) )
  4428.     end
  4429.  
  4430.  
  4431.     IF @20data is null
  4432.       return
  4433.     IF datalength( @20data ) > 39
  4434.     begin
  4435.         -- Get the originator_id for the first command 
  4436.         select @cmd_data_len = substring( @20data, 34, 2 )
  4437.         select @orig_srv_len = substring( @20data, 36, 2 )
  4438.         select @orig_db_len = substring( @20data, 38, 2 )
  4439.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4440.         begin 
  4441.             set @originator_id = null 
  4442.             select @originator_id = id from MSrepl_originators where
  4443.                 publisher_database_id = @publisher_database_id 
  4444.                 and UPPER(srvname) = upper(convert(sysname, substring( @20data, 40 + @cmd_data_len, @orig_srv_len )))
  4445.                 and dbname = substring( @20data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4446.             if @originator_id is null
  4447.             begin
  4448.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4449.                     (@publisher_database_id, substring( @20data, 40 + @cmd_data_len, @orig_srv_len ), substring( @20data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4450.                 select @originator_id = @@identity
  4451.             end
  4452.         end
  4453.         else
  4454.             select @originator_id = 0
  4455.  
  4456.         -- Now insert into MSrepl_commands
  4457.  
  4458.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4459.             substring(@20data,11 ,10),
  4460.             substring(@20data,29 ,4), 
  4461.             substring(@20data,21 ,4), 
  4462.             @originator_id, 
  4463.             substring(@20data,25 ,4), 
  4464.             convert(bit,substring(@20data,33 ,1)), 
  4465.             substring(@20data,40,@cmd_data_len) )
  4466.     end
  4467.  
  4468.     IF @21data is null
  4469.       return
  4470.     IF datalength( @21data ) > 39
  4471.     begin
  4472.         -- Get the originator_id for the first command 
  4473.         select @cmd_data_len = substring( @21data, 34, 2 )
  4474.         select @orig_srv_len = substring( @21data, 36, 2 )
  4475.         select @orig_db_len = substring( @21data, 38, 2 )
  4476.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4477.         begin 
  4478.             set @originator_id = null 
  4479.             select @originator_id = id from MSrepl_originators where
  4480.                 publisher_database_id = @publisher_database_id 
  4481.                 and UPPER(srvname) = upper(convert(sysname, substring( @21data, 40 + @cmd_data_len, @orig_srv_len )))
  4482.                 and dbname = substring( @21data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4483.             if @originator_id is null
  4484.             begin
  4485.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4486.                     (@publisher_database_id, substring( @21data, 40 + @cmd_data_len, @orig_srv_len ), substring( @21data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4487.                 select @originator_id = @@identity
  4488.             end
  4489.         end
  4490.         else
  4491.             select @originator_id = 0
  4492.  
  4493.         -- Now insert into MSrepl_commands
  4494.  
  4495.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4496.             substring(@21data,11 ,10),
  4497.             substring(@21data,29 ,4), 
  4498.             substring(@21data,21 ,4), 
  4499.             @originator_id, 
  4500.             substring(@21data,25 ,4), 
  4501.             convert(bit,substring(@21data,33 ,1)), 
  4502.             substring(@21data,40,@cmd_data_len) )
  4503.     end
  4504.  
  4505.     IF @22data is null
  4506.       return
  4507.     IF datalength( @22data ) > 39
  4508.     begin
  4509.         -- Get the originator_id for the first command 
  4510.         select @cmd_data_len = substring( @22data, 34, 2 )
  4511.         select @orig_srv_len = substring( @22data, 36, 2 )
  4512.         select @orig_db_len = substring( @22data, 38, 2 )
  4513.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4514.         begin 
  4515.             set @originator_id = null 
  4516.             select @originator_id = id from MSrepl_originators where
  4517.                 publisher_database_id = @publisher_database_id 
  4518.                 and UPPER(srvname) = upper(convert(sysname, substring( @22data, 40 + @cmd_data_len, @orig_srv_len )))
  4519.                 and dbname = substring( @22data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4520.             if @originator_id is null
  4521.             begin
  4522.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4523.                     (@publisher_database_id, substring( @22data, 40 + @cmd_data_len, @orig_srv_len ), substring( @22data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4524.                 select @originator_id = @@identity
  4525.             end
  4526.         end
  4527.         else
  4528.             select @originator_id = 0
  4529.  
  4530.         -- Now insert into MSrepl_commands
  4531.  
  4532.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4533.             substring(@22data,11 ,10),
  4534.             substring(@22data,29 ,4), 
  4535.             substring(@22data,21 ,4), 
  4536.             @originator_id, 
  4537.             substring(@22data,25 ,4), 
  4538.             convert(bit,substring(@22data,33 ,1)), 
  4539.             substring(@22data,40,@cmd_data_len) )
  4540.     end
  4541.  
  4542.     IF @23data is null
  4543.       return
  4544.     IF datalength( @23data ) > 39
  4545.     begin
  4546.         -- Get the originator_id for the first command 
  4547.         select @cmd_data_len = substring( @23data, 34, 2 )
  4548.         select @orig_srv_len = substring( @23data, 36, 2 )
  4549.         select @orig_db_len = substring( @23data, 38, 2 )
  4550.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4551.         begin 
  4552.             set @originator_id = null 
  4553.             select @originator_id = id from MSrepl_originators where
  4554.                 publisher_database_id = @publisher_database_id 
  4555.                 and UPPER(srvname) = upper(convert(sysname, substring( @23data, 40 + @cmd_data_len, @orig_srv_len )))
  4556.                 and dbname = substring( @23data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4557.             if @originator_id is null
  4558.             begin
  4559.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4560.                     (@publisher_database_id, substring( @23data, 40 + @cmd_data_len, @orig_srv_len ), substring( @23data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4561.                 select @originator_id = @@identity
  4562.             end
  4563.         end
  4564.         else
  4565.             select @originator_id = 0
  4566.  
  4567.         -- Now insert into MSrepl_commands
  4568.  
  4569.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4570.             substring(@23data,11 ,10),
  4571.             substring(@23data,29 ,4), 
  4572.             substring(@23data,21 ,4), 
  4573.             @originator_id, 
  4574.             substring(@23data,25 ,4), 
  4575.             convert(bit,substring(@23data,33 ,1)), 
  4576.             substring(@23data,40,@cmd_data_len) )
  4577.     end
  4578.  
  4579.     IF @24data is null
  4580.       return
  4581.     IF datalength( @24data ) > 39
  4582.     begin
  4583.         -- Get the originator_id for the first command 
  4584.         select @cmd_data_len = substring( @24data, 34, 2 )
  4585.         select @orig_srv_len = substring( @24data, 36, 2 )
  4586.         select @orig_db_len = substring( @24data, 38, 2 )
  4587.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4588.         begin 
  4589.             set @originator_id = null 
  4590.             select @originator_id = id from MSrepl_originators where
  4591.                 publisher_database_id = @publisher_database_id 
  4592.                 and UPPER(srvname) = upper(convert(sysname, substring( @24data, 40 + @cmd_data_len, @orig_srv_len )))
  4593.                 and dbname = substring( @24data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4594.             if @originator_id is null
  4595.             begin
  4596.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4597.                     (@publisher_database_id, substring( @24data, 40 + @cmd_data_len, @orig_srv_len ), substring( @24data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4598.                 select @originator_id = @@identity
  4599.             end
  4600.         end
  4601.         else
  4602.             select @originator_id = 0
  4603.  
  4604.         -- Now insert into MSrepl_commands
  4605.  
  4606.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4607.             substring(@24data,11 ,10),
  4608.             substring(@24data,29 ,4), 
  4609.             substring(@24data,21 ,4), 
  4610.             @originator_id, 
  4611.             substring(@24data,25 ,4), 
  4612.             convert(bit,substring(@24data,33 ,1)), 
  4613.             substring(@24data,40,@cmd_data_len) )
  4614.     end
  4615.  
  4616.  
  4617.     IF @25data is null
  4618.       return
  4619.     IF datalength( @25data ) > 39
  4620.     begin
  4621.         -- Get the originator_id for the first command 
  4622.         select @cmd_data_len = substring( @25data, 34, 2 )
  4623.         select @orig_srv_len = substring( @25data, 36, 2 )
  4624.         select @orig_db_len = substring( @25data, 38, 2 )
  4625.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4626.         begin 
  4627.             set @originator_id = null 
  4628.             select @originator_id = id from MSrepl_originators where
  4629.                 publisher_database_id = @publisher_database_id 
  4630.                 and UPPER(srvname) = upper(convert(sysname, substring( @25data, 40 + @cmd_data_len, @orig_srv_len )))
  4631.                 and dbname = substring( @25data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4632.             if @originator_id is null
  4633.             begin
  4634.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4635.                     (@publisher_database_id, substring( @25data, 40 + @cmd_data_len, @orig_srv_len ), substring( @25data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4636.                 select @originator_id = @@identity
  4637.             end
  4638.         end
  4639.         else
  4640.             select @originator_id = 0
  4641.  
  4642.         -- Now insert into MSrepl_commands
  4643.  
  4644.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4645.             substring(@25data,11 ,10),
  4646.             substring(@25data,29 ,4), 
  4647.             substring(@25data,21 ,4), 
  4648.             @originator_id, 
  4649.             substring(@25data,25 ,4), 
  4650.             convert(bit,substring(@25data,33 ,1)), 
  4651.             substring(@25data,40,@cmd_data_len) )
  4652.     end
  4653.  
  4654.  
  4655.     IF @26data is null
  4656.       return
  4657.     IF datalength( @26data ) > 39
  4658.     begin
  4659.         -- Get the originator_id for the first command 
  4660.         select @cmd_data_len = substring( @26data, 34, 2 )
  4661.         select @orig_srv_len = substring( @26data, 36, 2 )
  4662.         select @orig_db_len = substring( @26data, 38, 2 )
  4663.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4664.         begin 
  4665.             set @originator_id = null 
  4666.             select @originator_id = id from MSrepl_originators where
  4667.                 publisher_database_id = @publisher_database_id 
  4668.                 and UPPER(srvname) = upper(convert(sysname, substring( @26data, 40 + @cmd_data_len, @orig_srv_len )))
  4669.                 and dbname = substring( @26data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4670.             if @originator_id is null
  4671.             begin
  4672.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4673.                     (@publisher_database_id, substring( @26data, 40 + @cmd_data_len, @orig_srv_len ), substring( @26data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4674.                 select @originator_id = @@identity
  4675.             end
  4676.         end
  4677.         else
  4678.             select @originator_id = 0
  4679.  
  4680.         -- Now insert into MSrepl_commands
  4681.  
  4682.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4683.             substring(@26data,11 ,10),
  4684.             substring(@26data,29 ,4), 
  4685.             substring(@26data,21 ,4), 
  4686.             @originator_id, 
  4687.             substring(@26data,25 ,4), 
  4688.             convert(bit,substring(@26data,33 ,1)), 
  4689.             substring(@26data,40,@cmd_data_len) )
  4690.     end
  4691.  
  4692.  
  4693.     IF @@ERROR <> 0
  4694.       return (1)
  4695.  
  4696. go
  4697.  
  4698.  
  4699. raiserror(15339,-1,-1,'sp_MSvalidate_distpublisher')
  4700. go
  4701. CREATE PROCEDURE sp_MSvalidate_distpublisher
  4702. @publisher sysname,
  4703. @publisher_id smallint = NULL OUTPUT
  4704. as
  4705.  
  4706.     set nocount on
  4707.  
  4708.     declare @distribution_db sysname
  4709.     declare @retcode int
  4710.  
  4711.     -- Check if publisher is a defined as a distribution publisher at this distributor
  4712.     select @publisher_id = srvid from master.dbo.sysservers where UPPER(srvname) = UPPER(@publisher) 
  4713.     if @publisher_id is NULL
  4714.     begin
  4715.         raiserror (14080, 11, -1)
  4716.         return (1)
  4717.     end
  4718.  
  4719.     if not exists (select * from msdb..MSdistpublishers where UPPER(name) = UPPER(@publisher))
  4720.     begin
  4721.         raiserror (14080, 11, -1)
  4722.         return (1)
  4723.     end
  4724.  
  4725.  
  4726.     -- Check if client is in the correct distribution database
  4727.     exec @retcode = dbo.sp_helpdistributor @publisher = @publisher, @distribdb = @distribution_db OUTPUT
  4728.     if @@error <> 0 OR @retcode <> 0
  4729.     begin
  4730.         raiserror (14071, 16, -1)
  4731.         return (1)
  4732.     end
  4733.  
  4734.     -- Check if publisher is associated with a distribution database
  4735.     if @distribution_db is NULL
  4736.     begin
  4737.         raiserror (14071, 16, -1)
  4738.         return(1)
  4739.     end
  4740.  
  4741.     -- Check if client is in the distribution database 
  4742.     if @distribution_db <> db_name()
  4743.     begin
  4744.         raiserror(14071, 16, -1)
  4745.         return(1)
  4746.     end
  4747.  
  4748. go
  4749.  
  4750. raiserror(15339,-1,-1,'sp_MSdrop_distribution_agent')
  4751. GO
  4752. CREATE PROCEDURE sp_MSdrop_distribution_agent (
  4753.     @publisher_id smallint,
  4754.     @publisher_db sysname,
  4755.     @publication sysname,
  4756.     @subscriber_id smallint,
  4757.     @subscriber_db sysname,
  4758.     @subscription_type int,
  4759.     @keep_for_last_run          bit = 0
  4760. ) AS
  4761.  
  4762.  
  4763.     SET NOCOUNT ON
  4764.  
  4765.     /*
  4766.     ** Declarations.
  4767.     */
  4768.     DECLARE @stopcode       int
  4769.     DECLARE @retcode        int
  4770.     DECLARE @job_id         binary(16)
  4771.     DECLARE @is_continuous  bit
  4772.     DECLARE @local_job      bit
  4773.     DECLARE @publisher      sysname
  4774.     DECLARE @schedule_name  sysname
  4775.     DECLARE @job_command    nvarchar(512)
  4776.     DECLARE @name           nvarchar(100)
  4777.     DECLARE @agent_id       int
  4778.  
  4779.     select @stopcode = 1
  4780.     SELECT @job_id = job_id, @local_job = local_job, @name = name, @agent_id = id FROM MSdistribution_agents WHERE
  4781.         publisher_id = @publisher_id AND
  4782.         publisher_db = @publisher_db AND
  4783.         publication = @publication and
  4784.         subscriber_id = @subscriber_id and
  4785.         subscriber_db = @subscriber_db and
  4786.         subscription_type = @subscription_type
  4787.     
  4788.     -- Delete Perfmon instance
  4789.     dbcc deleteinstance ("SQL Replication Distribution", @name)
  4790.  
  4791.     select @publisher = srvname from master..sysservers where srvid = @publisher_id
  4792.  
  4793.     -- Return if not exists
  4794.     IF @local_job IS NULL
  4795.         RETURN(0)
  4796.  
  4797.     BEGIN TRAN
  4798.  
  4799.     IF @local_job = 1 and @keep_for_last_run = 0
  4800.     BEGIN
  4801.         IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE job_id = @job_id)
  4802.         BEGIN
  4803.             EXEC @retcode = msdb.dbo.sp_delete_job @job_id = @job_id
  4804.             IF @@ERROR <> 0 or @retcode <> 0
  4805.                 GOTO UNDO
  4806.         END
  4807.     END
  4808.  
  4809.     IF @local_job = 1 and @keep_for_last_run = 1
  4810.     BEGIN
  4811.             select @job_command=command from msdb.dbo.sysjobsteps where job_id=@job_id and step_id=2
  4812.  
  4813.             if PATINDEX('%-[Cc][Oo][Nn][Tt][Ii][Nn][Uu][Oo][Uu][Ss]%', @job_command) > 0
  4814.                 begin
  4815.                     select @is_continuous = 1
  4816.                     create table #sqlstatus(status nvarchar(20))
  4817.                     insert into #sqlstatus (status) exec master.dbo.xp_servicecontrol 'QUERYSTATE', 'SQLServerAgent'
  4818.                     if exists (select * from #sqlstatus where status='Running.') 
  4819.                             exec @stopcode = msdb.dbo.sp_stop_job @job_id = @job_id
  4820.                                  if @@ERROR<>0 GOTO UNDO
  4821.                     drop table #sqlstatus   
  4822.                     if @stopcode=0 
  4823.                         waitfor delay '00:00:30'
  4824.                 end
  4825.             
  4826.             EXEC @retcode = msdb.dbo.sp_update_job @job_id=@job_id, @delete_level=3 -- NOTE: Run once, success or failure!
  4827.             IF @@ERROR <> 0 or @retcode <> 0
  4828.                 GOTO UNDO
  4829.         
  4830.             EXEC @retcode = msdb.dbo.sp_delete_jobstep @job_id=@job_id, @step_id=3
  4831.             IF @@ERROR <> 0 or @retcode <> 0
  4832.                 GOTO UNDO
  4833.             EXEC @retcode = msdb.dbo.sp_delete_jobstep @job_id=@job_id, @step_id=1
  4834.             IF @@ERROR <> 0 or @retcode <> 0
  4835.                 GOTO UNDO
  4836.  
  4837.             select @job_command=command from msdb.dbo.sysjobsteps where job_id=@job_id and step_id=1        
  4838.             select @job_command = @job_command + ' -UnSubscribe 0 '  -- currently the value does not really matter
  4839.             
  4840.             EXEC @retcode = msdb.dbo.sp_update_jobstep @job_id=@job_id, @step_id=1, 
  4841.                                 @on_success_action=1, 
  4842.                                 @on_fail_action=2, 
  4843.                                 @command=@job_command
  4844.             IF @@ERROR <> 0 or @retcode <> 0
  4845.                 GOTO UNDO
  4846.  
  4847.             
  4848.             select @schedule_name = formatmessage(20532)
  4849.             EXEC @retcode = msdb.dbo.sp_update_jobschedule @job_id=@job_id, @name=@schedule_name, @freq_subday_type = 2, @freq_subday_interval=30
  4850.             IF @@ERROR<>0 or @retcode<>0
  4851.                 GOTO UNDO
  4852.             
  4853.             if (@is_continuous  = 1) and (@stopcode = 0)
  4854.                 begin
  4855.                     EXEC @retcode = msdb.dbo.sp_start_job @job_id=@job_id
  4856.                      if @@ERROR<>0 
  4857.                         GOTO UNDO
  4858.                 end
  4859.             /*
  4860.             ** The last run of this job will be as scheduled
  4861.             */
  4862.     END
  4863.  
  4864.     -- Remove agent entry
  4865.     DELETE MSdistribution_agents WHERE id = @agent_id
  4866.     IF @@ERROR <> 0 
  4867.         GOTO UNDO
  4868.  
  4869.     -- Remove associated history 
  4870.     DELETE MSdistribution_history WHERE agent_id = @agent_id
  4871.     IF @@ERROR <> 0 
  4872.         GOTO UNDO
  4873.  
  4874.     -- Update global replication status table
  4875.     EXEC dbo.sp_MSupdate_replication_status
  4876.         @publisher,
  4877.         @publisher_db,
  4878.         @publication,
  4879.         @agent_type = 3,
  4880.         @agent_name = @name,
  4881.         @status = -1    -- delete status
  4882.  
  4883.     COMMIT TRAN
  4884.  
  4885.     RETURN(0)
  4886.  
  4887. UNDO:
  4888.     if @@TRANCOUNT = 1
  4889.         ROLLBACK TRAN
  4890.     else
  4891.         COMMIT TRAN
  4892.     return(1)
  4893. GO
  4894.  
  4895. raiserror(15339,-1,-1,'sp_MSdrop_distribution_agentid')
  4896. GO
  4897. CREATE PROCEDURE sp_MSdrop_distribution_agentid (
  4898.     @agent_id int
  4899. ) AS
  4900.  
  4901.  
  4902.     SET NOCOUNT ON
  4903.  
  4904.     /*
  4905.     ** Declarations.
  4906.     */
  4907.     DECLARE @name           nvarchar(100)
  4908.     DECLARE @publisher      sysname
  4909.     DECLARE @publisher_db   sysname
  4910.     DECLARE @publication    sysname
  4911.  
  4912.     SELECT @name = name, @publisher = srvname, @publisher_db = publisher_db, @publication = publication FROM 
  4913.         MSdistribution_agents, master..sysservers WHERE 
  4914.         id = @agent_id and
  4915.         srvid = publisher_id
  4916.     
  4917.     -- Delete Perfmon instance
  4918.     dbcc deleteinstance ("SQL Replication Distribution", @name)
  4919.  
  4920.     -- Remove agent entry
  4921.     DELETE MSdistribution_agents WHERE id = @agent_id
  4922.     IF @@ERROR <> 0 
  4923.         return 1
  4924.  
  4925.     -- Update global replication status table
  4926.     EXEC dbo.sp_MSupdate_replication_status
  4927.         @publisher,
  4928.         @publisher_db,
  4929.         @publication,
  4930.         @publication_type = 1,
  4931.         @agent_type = 3,
  4932.         @agent_name = @name,
  4933.         @status = -1    -- delete status
  4934.  
  4935.     return 0
  4936.  
  4937. GO
  4938.  
  4939. raiserror(15339,-1,-1,'sp_MSdrop_merge_agentid')
  4940. GO
  4941. CREATE PROCEDURE sp_MSdrop_merge_agentid (
  4942.     @agent_id int
  4943. ) AS
  4944.  
  4945.  
  4946.     SET NOCOUNT ON
  4947.  
  4948.     /*
  4949.     ** Declarations.
  4950.     */
  4951.     DECLARE @name           nvarchar(100)
  4952.     DECLARE @publisher      sysname
  4953.     DECLARE @publisher_db   sysname
  4954.     DECLARE @publication    sysname
  4955.  
  4956.     SELECT @name = name, @publisher = srvname, @publisher_db = publisher_db, @publication = publication FROM 
  4957.         MSmerge_agents, master..sysservers WHERE 
  4958.         id = @agent_id and
  4959.         srvid = publisher_id
  4960.     
  4961.     -- Delete Perfmon instance
  4962.     dbcc deleteinstance ("SQL Replication Merge", @name)
  4963.  
  4964.     -- Remove agent entry
  4965.     DELETE MSmerge_agents WHERE id = @agent_id
  4966.     IF @@ERROR <> 0 
  4967.         return 1
  4968.  
  4969.     -- Update global replication status table
  4970.     EXEC dbo.sp_MSupdate_replication_status
  4971.         @publisher,
  4972.         @publisher_db,
  4973.         @publication,
  4974.         @agent_type = 4,
  4975.         @agent_name = @name,
  4976.         @status = -1    -- delete status
  4977.  
  4978.     return 0
  4979.  
  4980. GO
  4981.  
  4982. raiserror(15339,-1,-1,'sp_MSadd_distribution_agent')
  4983. GO
  4984. CREATE PROCEDURE sp_MSadd_distribution_agent (
  4985.     @name nvarchar(100) = NULL,
  4986.     @publisher_id smallint,
  4987.     @publisher_db sysname,
  4988.     @publication sysname,  
  4989.     @subscriber_id smallint,
  4990.     @subscriber_db sysname,
  4991.     @subscription_type int, -- have to have it to identify a distribution agent.
  4992.     @local_job bit, 
  4993.  
  4994.     @frequency_type int = 64,
  4995.     @frequency_interval int = 1,
  4996.     @frequency_relative_interval int = 1,
  4997.     @frequency_recurrence_factor int = 0,
  4998.     @frequency_subday int = 4,
  4999.     @frequency_subday_interval int = 5,
  5000.     @active_start_time_of_day int = 0,
  5001.     @active_end_time_of_day int = 235959,
  5002.     @active_start_date int = 0,
  5003.     @active_end_date int = 99991231,
  5004.  
  5005.     @retryattempts int = 10,
  5006.     @retrydelay int = 1,
  5007.     
  5008.     @command nvarchar(4000) = NULL,
  5009.     @agent_id int = NULL OUTPUT,
  5010.     @distribution_jobid binary(16) = NULL OUTPUT
  5011. ) AS
  5012.  
  5013.  
  5014.     SET NOCOUNT ON
  5015.  
  5016.     /*
  5017.     ** Declarations.
  5018.     */
  5019.     DECLARE @retcode            int
  5020.     DECLARE @database           sysname
  5021.     DECLARE @profile_id         int
  5022.     DECLARE @distribution_type  int
  5023.     DECLARE @publisher          sysname
  5024.     DECLARE @category_name      sysname
  5025.     DECLARE @subscriber         sysname
  5026.     declare @publisher_database_id int
  5027.     select @database = DB_NAME()
  5028.  
  5029.  
  5030.     /*
  5031.     ** Initializations
  5032.     */
  5033.     
  5034.     BEGIN TRAN
  5035.  
  5036.     -- Try to drop it first
  5037.     EXEC @retcode = dbo.sp_MSdrop_distribution_agent 
  5038.         @publisher_id = @publisher_id,
  5039.         @publisher_db = @publisher_db,
  5040.         @publication = @publication,
  5041.         @subscriber_id = @subscriber_id,
  5042.         @subscriber_db = @subscriber_db,
  5043.         @subscription_type = @subscription_type
  5044.     IF @@ERROR <> 0 or @retcode <> 0
  5045.         GOTO UNDO
  5046.  
  5047.     /* Code for distribution agent type in MSagent_profiles */
  5048.     SELECT @distribution_type = 3
  5049.  
  5050.     SELECT @profile_id = profile_id
  5051.     FROM msdb..MSagent_profiles
  5052.     WHERE agent_type = @distribution_type
  5053.         AND def_profile = 1
  5054.  
  5055.     IF @profile_id IS NULL
  5056.         GOTO UNDO
  5057.  
  5058.     select @publisher = srvname from master..sysservers where srvid = @publisher_id
  5059.     select @subscriber = srvname from master..sysservers where srvid = @subscriber_id
  5060.     select @publisher_database_id = id from MSpublisher_databases where 
  5061.         publisher_id = @publisher_id and
  5062.         publisher_db = @publisher_db
  5063.  
  5064.     /* 
  5065.     ** Insert row
  5066.     */
  5067.     INSERT INTO MSdistribution_agents (name, publisher_database_id, publisher_id, publisher_db, publication, 
  5068.             subscriber_id, subscriber_db, subscription_type, local_job, 
  5069.             subscription_guid, profile_id)
  5070.         VALUES ('',@publisher_database_id, @publisher_id, @publisher_db, @publication, 
  5071.             @subscriber_id, @subscriber_db, @subscription_type, @local_job, 
  5072.             newid(), @profile_id)
  5073.     IF @@ERROR <> 0
  5074.         GOTO UNDO
  5075.     
  5076.     SELECT @agent_id = @@IDENTITY
  5077.  
  5078.     -- Add Perfmoon instance
  5079.     dbcc addinstance ("SQL Replication Distribution", @name)
  5080.  
  5081.     -- Set agent name
  5082.     if @subscriber is NULL select @subscriber = ''
  5083.     if @subscriber_db is NULL select @subscriber_db =''
  5084.     IF @name IS NULL
  5085.     BEGIN
  5086.         /*
  5087.         ** Sacrifice 1-2 character from each of (@publisher,@publication,
  5088.         ** @publisher_db,subscriber) to allow 4 more indentity digits in
  5089.         ** the distribution agent name. This will hopefully provide better
  5090.         ** guarantee of agent name uniqueness.
  5091.         */
  5092.         if @publication is NOT NULL and (LOWER(@publication)<>'all')
  5093.             BEGIN
  5094.             SELECT @name = CONVERT(nvarchar(21),@publisher ) + '-' + 
  5095.                 CONVERT(nvarchar(21),@publisher_db) + '-' + 
  5096.                 CONVERT(nvarchar(21),@publication) + '-' + 
  5097.                 CONVERT(nvarchar(21),@subscriber) + '-' +
  5098.                 CONVERT(nvarchar, @@IDENTITY)
  5099.             END
  5100.         else
  5101.             SELECT @name = CONVERT(nvarchar(28),@publisher ) + '-' + 
  5102.                 CONVERT(nvarchar(28),@publisher_db) + '-' + 
  5103.                 CONVERT(nvarchar(28),@subscriber) + '-' + 
  5104.                 CONVERT(nvarchar, @@IDENTITY)
  5105.     END
  5106.  
  5107.     IF @local_job = 1
  5108.     BEGIN
  5109.  
  5110.  
  5111. --    *******WORKAROUND*******
  5112.         DECLARE @nullchar nchar(20)
  5113.         SELECT @nullchar = NULL
  5114. --    *******WORKAROUND*******
  5115.         -- Get Distribution category name (assumes category_id = 10)
  5116.         select @category_name = name FROM msdb.dbo.syscategories where category_id = 10
  5117.  
  5118.         if @frequency_recurrence_factor is null
  5119.             select @frequency_recurrence_factor = 0
  5120.  
  5121.         EXECUTE @retcode = dbo.sp_MSadd_repl_job
  5122.         @name = @name,
  5123.         @subsystem = 'Distribution',
  5124.         @server = @@SERVERNAME,
  5125.         @databasename = @database,
  5126.         @enabled = 1,
  5127.         @freqtype = @frequency_type,
  5128.         @freqinterval = @frequency_interval,
  5129.         @freqsubtype = @frequency_subday,
  5130.         @freqsubinterval = @frequency_subday_interval,
  5131.         @freqrelativeinterval = @frequency_relative_interval,
  5132.         @freqrecurrencefactor = @frequency_recurrence_factor,
  5133.         @activestartdate = @active_start_date,
  5134.         @activeenddate = @active_end_date,
  5135.         @activestarttimeofday = @active_start_time_of_day,
  5136.         @activeendtimeofday = @active_end_time_of_day,
  5137.         @nextrundate = 0,
  5138.         @nextruntime = 0,
  5139.         @runpriority = 0,
  5140.         @emailoperatorname = NULL,
  5141.         @retryattempts = @retryattempts,
  5142.         @retrydelay = @retrydelay,
  5143.         @command = @command,
  5144.         @loghistcompletionlevel = 0,
  5145.         @emailcompletionlevel = 0,
  5146.         @description = NULL,
  5147.         @category_name = @category_name,
  5148.         @failure_detection = 1,
  5149.         @agent_id = @agent_id,
  5150.         @job_id = @distribution_jobid OUTPUT
  5151.  
  5152.        IF @@ERROR <> 0 or @retcode <> 0
  5153.             GOTO UNDO
  5154.     END
  5155.     ELSE 
  5156.     BEGIN
  5157.         -- Generate a job GUID for remote agents. This will be used by the UI to uniquely
  5158.         -- identify rows returned by the enums
  5159.         set @distribution_jobid = newid();
  5160.     END
  5161.  
  5162.     UPDATE MSdistribution_agents SET name = @name,
  5163.         job_id = @distribution_jobid WHERE
  5164.         id = @agent_id
  5165.  
  5166.     IF @@ERROR <> 0
  5167.         GOTO UNDO
  5168.  
  5169.     -- Update global replication status table
  5170.     EXEC dbo.sp_MSupdate_replication_status
  5171.         @publisher,
  5172.         @publisher_db,
  5173.         @publication,
  5174.         @agent_type = 3,
  5175.         @agent_name = @name,
  5176.         @status = 0     -- not running status
  5177.  
  5178.     COMMIT TRAN
  5179.  
  5180.     RETURN(0)
  5181. UNDO:
  5182.     if @@TRANCOUNT = 1
  5183.         ROLLBACK TRAN
  5184.     else
  5185.         COMMIT TRAN
  5186.     return(1)
  5187. GO
  5188.  
  5189. raiserror(15339,-1,-1,'sp_MSdrop_agent_entry')
  5190. GO
  5191. /*
  5192. ** This one is reserved for future use.
  5193. */
  5194. CREATE PROCEDURE sp_MSdrop_agent_entry (
  5195. @pub_srvid      smallint,
  5196. @pub_db_name    sysname,
  5197. @publication    sysname,
  5198. @sub_srvid      smallint,
  5199. @sub_db_name    sysname
  5200. ) AS
  5201. delete from MSmerge_agents where publisher_id = @pub_srvid AND publisher_db = @pub_db_name AND publication=@publication
  5202.                                     AND subscriber_id = @sub_srvid AND subscriber_db = @sub_db_name
  5203. if @@ERROR<>0 return (1)
  5204. return (0)
  5205. GO
  5206.  
  5207.  
  5208. raiserror(15339,-1,-1,'sp_MSdrop_merge_agent')
  5209. GO
  5210. CREATE PROCEDURE sp_MSdrop_merge_agent (
  5211.     @publisher          sysname,
  5212.     @publisher_db       sysname,
  5213.     @publication        sysname,
  5214.     @subscriber         sysname,
  5215.     @subscriber_db      sysname,
  5216.     @keep_for_last_run  bit = 0 -- if the agent needs to stay to run one more time; default is NO
  5217. ) AS
  5218.  
  5219.  
  5220.     SET NOCOUNT ON
  5221.  
  5222.     /*
  5223.     ** Declarations.
  5224.     */
  5225.     DECLARE @retcode    int
  5226.     DECLARE @job_id     binary(16)
  5227.     DECLARE @local_job  bit
  5228.     DECLARE @publisher_id smallint
  5229.     DECLARE @subscriber_id smallint
  5230.     DECLARE @job_command nvarchar(512)
  5231.     DECLARE @name nvarchar(100)
  5232.     DECLARE @agent_id   int
  5233.  
  5234.     /*
  5235.     ** Initializations
  5236.     */
  5237.     -- Get subscriber info
  5238.     select @subscriber_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  5239.     select @publisher_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)
  5240.  
  5241.  
  5242.     SELECT @job_id = job_id, @local_job = local_job, @name = name, @agent_id = id FROM MSmerge_agents WHERE
  5243.         publisher_id = @publisher_id AND
  5244.         publisher_db = @publisher_db AND
  5245.         publication = @publication and
  5246.         subscriber_id = @subscriber_id and
  5247.         subscriber_db = @subscriber_db 
  5248.  
  5249.     -- Delete Perfmon instance
  5250.     dbcc deleteinstance ("SQL Replication Merge", @name)
  5251.  
  5252.     -- Return if not exists
  5253.     IF @local_job IS NULL
  5254.         RETURN(0)
  5255.  
  5256.     BEGIN TRAN
  5257.  
  5258.     IF @keep_for_last_run = 0
  5259.     BEGIN
  5260.         if @local_job=1
  5261.         begin
  5262.             IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE job_id = @job_id)
  5263.             begin
  5264.                 EXEC @retcode = msdb.dbo.sp_delete_job @job_id = @job_id
  5265.                 IF @@ERROR <> 0 or @retcode <> 0
  5266.                     GOTO UNDO
  5267.             end
  5268.         end
  5269.     END
  5270.  
  5271.     IF @local_job = 1 and @keep_for_last_run = 1
  5272.     BEGIN
  5273.         IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE job_id = @job_id)
  5274.         BEGIN
  5275.             EXEC @retcode = msdb.dbo.sp_update_job @job_id=@job_id, @delete_level=3 -- NOTE: Only once, success or failure!
  5276.             IF @@ERROR <> 0 or @retcode <> 0
  5277.                 GOTO UNDO
  5278.             EXEC @retcode = msdb.dbo.sp_delete_jobstep @job_id=@job_id, @step_id=3
  5279.             IF @@ERROR <> 0 or @retcode <> 0
  5280.                 GOTO UNDO
  5281.             EXEC @retcode = msdb.dbo.sp_delete_jobstep @job_id=@job_id, @step_id=1
  5282.             IF @@ERROR <> 0 or @retcode <> 0
  5283.                 GOTO UNDO
  5284.  
  5285.             select @job_command=command from msdb.dbo.sysjobsteps where job_id=@job_id and step_id=1        
  5286.             select @job_command = @job_command + ' -AgentType 4 '
  5287.             
  5288.             EXEC @retcode = msdb.dbo.sp_update_jobstep @job_id=@job_id, @step_id=1, 
  5289.                 @on_success_action = 1,
  5290.                 @on_fail_action = 2,
  5291.                 @command=@job_command
  5292.             IF @@ERROR <> 0 or @retcode <> 0
  5293.                 GOTO UNDO
  5294.         END
  5295.     END
  5296.  
  5297.     DELETE MSmerge_agents WHERE id = @agent_id
  5298.     IF @@ERROR <> 0 
  5299.         GOTO UNDO
  5300.  
  5301.     -- Remove history       
  5302.     DELETE MSmerge_history WHERE agent_id = @agent_id 
  5303.     IF @@ERROR <> 0 
  5304.         GOTO UNDO
  5305.  
  5306.     -- Update global replication status table
  5307.     EXEC dbo.sp_MSupdate_replication_status
  5308.         @publisher,
  5309.         @publisher_db,
  5310.         @publication,
  5311.         @agent_type = 4,
  5312.         @agent_name = @name,
  5313.         @status = -1    -- delete status 
  5314.  
  5315.     COMMIT TRAN
  5316.  
  5317.     RETURN(0)
  5318.  
  5319. UNDO:
  5320.     if @@TRANCOUNT = 1
  5321.         ROLLBACK TRAN
  5322.     else
  5323.         COMMIT TRAN
  5324.     return(1)
  5325. GO
  5326.  
  5327. raiserror(15339,-1,-1,'sp_MSadd_merge_agent')
  5328. GO
  5329. CREATE PROCEDURE sp_MSadd_merge_agent (
  5330.     @name                           nvarchar(100) = NULL,
  5331.     @publisher                      sysname,                    /* Publisher server */
  5332.     @publisher_db                   sysname,                    /* Publisher database */
  5333.     @publication                    sysname,                    /* Publication name */
  5334.     @subscriber                     sysname,                    /* Subscriber server */
  5335.     @subscriber_db                  sysname,                    /* Subscription database */
  5336.     @local_job                      bit,
  5337.     @frequency_type                 int = NULL,
  5338.     @frequency_interval             int = NULL,             
  5339.     @frequency_relative_interval    int = NULL, 
  5340.     @frequency_recurrence_factor    int = NULL, 
  5341.     @frequency_subday               int = NULL,
  5342.     @frequency_subday_interval      int = NULL,    
  5343.     @active_start_time_of_day       int = NULL, 
  5344.     @active_end_time_of_day         int = NULL,         
  5345.     @active_start_date              int = NULL, 
  5346.     @active_end_date                int = NULL,
  5347.     @optional_command_line          nvarchar(255) = '',     /* Optional command line arguments */
  5348.     @merge_jobid                    binary(16) = NULL OUTPUT
  5349.     ) AS
  5350.  
  5351.     SET NOCOUNT ON
  5352.  
  5353.     /*
  5354.     ** Declarations.
  5355.     */
  5356.     declare @retcode        int
  5357.     DECLARE @publisher_id   smallint
  5358.     DECLARE @subscriber_id  smallint
  5359.     DECLARE @profile_id     int
  5360.     DECLARE @merge_type     int
  5361.     DECLARE @command        nvarchar(4000)
  5362.  
  5363.     DECLARE @subscriber_security_mode       int                 /* 0 standard; 1 integrated */
  5364.     DECLARE @subscriber_login               sysname 
  5365.     DECLARE @subscriber_password            sysname 
  5366.     DECLARE @subscriber_datasource_type     int     /* 0 SQL Server, 1 ODBC, 2 Jet, 3 OLEDB */
  5367.     DECLARE @distributor                    sysname 
  5368.     DECLARE @distributor_security_mode      int                     /* 0 standard; 1 integrated */
  5369.     DECLARE @distributor_login              sysname 
  5370.     DECLARE @distributor_password           sysname
  5371.     DECLARE @database                       sysname
  5372.     DECLARE @agent_id                       int
  5373.     DECLARE @category_name                  sysname
  5374.     DECLARE @dsn_subscriber                 tinyint
  5375.     DECLARE @jet_subscriber                 tinyint
  5376.     DECLARE @oledb_subscriber               tinyint
  5377.     DECLARE @exchange_subscriber            tinyint
  5378.     DECLARE @oracle_subscriber              tinyint
  5379.     DECLARE @platform_nt                    binary
  5380.     DECLARE @provider_name                    sysname
  5381.  
  5382.     set @subscriber_security_mode = 1
  5383.     set @subscriber_login = NULL
  5384.     set @subscriber_password = NULL
  5385.     set @distributor = @@SERVERNAME
  5386.  
  5387.     set @dsn_subscriber = 1    /* Const: subscriber type 'dsn' */ 
  5388.     set @jet_subscriber = 2   
  5389.     set @oledb_subscriber = 3 
  5390.     set @exchange_subscriber = 4
  5391.     set @oracle_subscriber = 5 
  5392.  
  5393.     set @platform_nt = 0x1  
  5394.     
  5395.     -- Set null @optional_command_line to empty string to avoid string concat problem
  5396.     if @optional_command_line is null
  5397.         set @optional_command_line = ''
  5398.  
  5399.     -- Get subscriber security context
  5400.     select  @subscriber_security_mode = security_mode,
  5401.             @subscriber_login = login,
  5402.             @subscriber_password = password
  5403.         from MSsubscriber_info where
  5404.             UPPER(publisher) = UPPER(@publisher) and
  5405.             UPPER(subscriber) = UPPER(@subscriber)
  5406.             
  5407.     -- Always use integrated security on winNT
  5408.     if (@platform_nt = platform() & @platform_nt )
  5409.         set @distributor_security_mode = 1
  5410.     else
  5411.     begin
  5412.         select  @distributor_security_mode = 0,
  5413.                 @distributor_login  = login,
  5414.                 @distributor_password = password
  5415.             from msdb..MSdistpublishers where UPPER(name) = UPPER(@@servername)
  5416.     end
  5417.     
  5418.     /*
  5419.     ** Initializations
  5420.     */
  5421.     -- Get subscriber info
  5422.     select @subscriber_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  5423.     select @publisher_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)
  5424.  
  5425.     select @subscriber_datasource_type = type
  5426.         from MSsubscriber_info 
  5427.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  5428.  
  5429.     /*
  5430.     ** Jet and Oracle subscribers are actually added to MSsubscriber_info as OLE DB subscribers,
  5431.     ** since they can be used in transactional replication also.
  5432.     ** Map the type to Jet or Oracle based on OLE DB provider name.
  5433.     */
  5434.     if (@subscriber_datasource_type = @oledb_subscriber) 
  5435.     BEGIN
  5436.         select @provider_name = providername from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  5437.         if (upper(@provider_name) = 'MICROSOFT.JET.OLEDB.4.0')
  5438.             select @subscriber_datasource_type = @jet_subscriber
  5439.         else if (upper(@provider_name) = 'MSDAORA')
  5440.             select @subscriber_datasource_type = @oracle_subscriber
  5441.     END
  5442.     
  5443.     if (@subscriber_datasource_type IS NULL)
  5444.         select @subscriber_datasource_type = 0
  5445.  
  5446.     BEGIN TRAN
  5447.  
  5448.     -- Try to drop it first
  5449.     EXEC dbo.sp_MSdrop_merge_agent 
  5450.         @publisher = @publisher,
  5451.         @publisher_db = @publisher_db,
  5452.         @publication = @publication,
  5453.         @subscriber = @subscriber,
  5454.         @subscriber_db = @subscriber_db
  5455.           
  5456.     IF @@ERROR <> 0
  5457.         GOTO UNDO
  5458.  
  5459.     /* Code for merge agent type in MSagent_profiles */
  5460.     SELECT @merge_type = 4
  5461.  
  5462.     SELECT @profile_id = profile_id
  5463.     FROM msdb..MSagent_profiles
  5464.     WHERE agent_type = @merge_type
  5465.         AND def_profile = 1
  5466.  
  5467.     IF @profile_id IS NULL
  5468.         RETURN (1)
  5469.  
  5470.     /* 
  5471.     ** Insert row
  5472.     */
  5473.     INSERT INTO MSmerge_agents (name, publisher_id, publisher_db, publication, 
  5474.          subscriber_id, subscriber_db, local_job, profile_id)
  5475.          VALUES ('',@publisher_id, @publisher_db, @publication, 
  5476.          @subscriber_id, @subscriber_db, @local_job, @profile_id)
  5477.     IF @@ERROR <> 0
  5478.         GOTO UNDO
  5479.  
  5480.     set @agent_id = @@IDENTITY
  5481.     
  5482.     if @frequency_type is NULL
  5483.         set @frequency_type = 4     /* Daily */
  5484.     if @frequency_interval is NULL
  5485.         set @frequency_interval = 1
  5486.     if @frequency_relative_interval is NULL
  5487.         set @frequency_relative_interval = 1
  5488.     if @frequency_recurrence_factor is NULL
  5489.         set @frequency_recurrence_factor = 0
  5490.     if @frequency_subday is NULL
  5491.         set @frequency_subday = 8   /* Hour */
  5492.     if @frequency_subday_interval is NULL
  5493.         set @frequency_subday_interval = 1
  5494.     if @active_start_time_of_day is NULL
  5495.         set @active_start_time_of_day = 0
  5496.     if @active_end_time_of_day is NULL
  5497.         set @active_end_time_of_day = 235959
  5498.     if @active_start_date is NULL
  5499.         set @active_start_date = 0
  5500.     if @active_end_date is NULL
  5501.         set @active_end_date = 99991231
  5502.  
  5503.     IF @name IS NULL
  5504.         SELECT @name = CONVERT(nvarchar(21),@publisher ) + '-' + CONVERT(nvarchar(21),@publisher_db) + '-' + 
  5505.                         CONVERT(nvarchar(21),@publication) + '-' + CONVERT(nvarchar(21),@subscriber) + '-' +
  5506.                             CONVERT(nvarchar, @@IDENTITY)
  5507.     
  5508.     -- Add Perfmoon instance
  5509.     dbcc addinstance ("SQL Replication Merge", @name)
  5510.  
  5511.     IF @local_job = 1
  5512.     BEGIN
  5513.  
  5514.     /* Construct task command */
  5515.  
  5516.     select @command = '-Publisher ' + @publisher + ' -PublisherDB ' + QUOTENAME(@publisher_db) + ' '
  5517.     select @command = @command + '-Publication ' + QUOTENAME(@publication) + ' '
  5518.     select @command = @command + '-Subscriber ' + QUOTENAME(@subscriber)  + ' '
  5519.  
  5520.     if (@subscriber_datasource_type = 0)
  5521.         select @command = @command + '-SubscriberDB ' + QUOTENAME(@subscriber_db) + ' '
  5522.         
  5523.     if (@subscriber_datasource_type <> 0)
  5524.         select @command = @command + '-SubscriberType ' + convert(nvarchar(10),@subscriber_datasource_type) + ' '
  5525.     
  5526.     select @command = @command + @optional_command_line
  5527.     select @command = @command + '-Distributor ' + @distributor + ' '
  5528.  
  5529.     select @command = @command + '-DistributorSecurityMode ' + 
  5530.         convert(nvarchar(10),@distributor_security_mode) +  ' ' 
  5531.     if @distributor_security_mode <> 1
  5532.     begin
  5533.         if @distributor_login is not NULL
  5534.             select @command = @command + '-DistributorLogin ' + @distributor_login + ' '
  5535.         if @distributor_password is not NULL
  5536.             select @command = @command + '-DistributorEncryptedPassword ' + quotename(@distributor_password) + ' '
  5537.     end
  5538.  
  5539.     select @database = db_name()
  5540.  
  5541.     -- Get Merge category name (assumes category_id = 14)
  5542.     select @category_name = name FROM msdb.dbo.syscategories where category_id = 14
  5543.  
  5544.     EXEC @retcode = dbo.sp_MSadd_repl_job
  5545.             @name = @name,
  5546.             @subsystem = 'Merge',
  5547.             @server = @@SERVERNAME,
  5548.             @databasename = @database,
  5549.             @enabled = 1,
  5550.             @freqtype = @frequency_type,
  5551.             @freqinterval = @frequency_interval,
  5552.             @freqsubtype = @frequency_subday,
  5553.             @freqsubinterval = @frequency_subday_interval,
  5554.             @freqrelativeinterval = @frequency_relative_interval,
  5555.             @freqrecurrencefactor = @frequency_recurrence_factor,
  5556.             @activestartdate = @active_start_date,
  5557.             @activeenddate = @active_end_date,
  5558.             @activestarttimeofday = @active_start_time_of_day,
  5559.             @activeendtimeofday = @active_end_time_of_day,
  5560.             @command = @command,
  5561.             @category_name = @category_name,
  5562.             @failure_detection = 1,
  5563.             @agent_id = @agent_id,
  5564.             @retryattempts = 10,
  5565.             @retrydelay = 1,
  5566.             @job_id = @merge_jobid OUTPUT
  5567.             
  5568.         if @@ERROR <> 0 or @retcode <> 0
  5569.             goto UNDO
  5570.     END /* for local_job = 1 */
  5571.     ELSE 
  5572.     BEGIN
  5573.         -- Generate a job GUID for remote agents. This will be used by the UI to uniquely
  5574.         -- identify rows returned by the enums
  5575.         set @merge_jobid = newid();
  5576.     END
  5577.             
  5578.     UPDATE MSmerge_agents SET name = @name,
  5579.         job_id = @merge_jobid WHERE
  5580.         id = @agent_id
  5581.  
  5582.     IF @@ERROR <> 0
  5583.         GOTO UNDO
  5584.  
  5585.     -- Update global replication status table
  5586.     EXEC dbo.sp_MSupdate_replication_status
  5587.         @publisher,
  5588.         @publisher_db,
  5589.         @publication,
  5590.         @publication_type = 1, -- Merge 
  5591.         @agent_type = 4,
  5592.         @agent_name = @name,
  5593.         @status = 0     -- not running status
  5594.  
  5595.     COMMIT TRAN
  5596.  
  5597.     RETURN(0)
  5598.  
  5599. UNDO:
  5600.     if @@TRANCOUNT = 1
  5601.         ROLLBACK TRAN
  5602.     else
  5603.         COMMIT TRAN
  5604.     return(1)
  5605. GO
  5606.  
  5607. raiserror(15339,-1,-1,'sp_MSdrop_subscription')
  5608. GO
  5609. CREATE PROCEDURE sp_MSdrop_subscription
  5610. @publisher sysname,
  5611. @publisher_db sysname,
  5612. @subscriber sysname,
  5613. @article_id int = NULL,
  5614. @subscriber_db sysname = NULL,
  5615. @publication sysname = NULL,
  5616. @article sysname = NULL
  5617.  
  5618. as
  5619.  
  5620.     set nocount on
  5621.  
  5622.     declare @publisher_id smallint
  5623.     declare @subscriber_id smallint
  5624.     declare @name nvarchar (100)
  5625.     declare @retcode int
  5626.     declare @push tinyint
  5627.     declare @anonymous tinyint
  5628.     declare @keep_for_last_run bit
  5629.     declare @virtual smallint
  5630.     declare @virtual_anonymous smallint
  5631.     declare @independent_agent bit
  5632.     declare @publication_id int
  5633.     declare @subscription_type int
  5634.     declare @thirdparty_flag bit
  5635.     declare @id             int
  5636.     declare @publication_name sysname
  5637.  
  5638.     select @push = 0        -- const: push subscription type 
  5639.     select @anonymous = 2   -- const: push subscription type 
  5640.     select @virtual = -1    -- const: virtual subscriber id 
  5641.     select @virtual_anonymous = -2  -- const: virtual anonymous subscriber id 
  5642.  
  5643.     -- Save off name for dummy status row
  5644.     select @publication_name = @publication
  5645.  
  5646.     -- Check if publisher is a defined as a distribution publisher in the current database
  5647.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  5648.     if @retcode <> 0
  5649.     begin
  5650.         return(1)
  5651.     end
  5652.  
  5653.     -- Check if subscriber exists
  5654.     if @subscriber is null
  5655.     begin
  5656.         select @subscriber_id = @virtual
  5657.         -- hardcoded in sp_MSadd_subscription
  5658.         select @subscriber_db = 'virtual'
  5659.     end
  5660.     else
  5661.         select @subscriber_id = srvid from master..sysservers, MSsubscriber_info where 
  5662.             UPPER(srvname) = UPPER(@subscriber) and
  5663.             UPPER(subscriber) = UPPER(@subscriber) and
  5664.             UPPER(publisher) = UPPER(@publisher)
  5665.     if @subscriber_id is NULL
  5666.     begin
  5667.         raiserror (20032, 16, -1, @subscriber, @publisher) 
  5668.         return (1)
  5669.     end
  5670.  
  5671.     -- If publication exists this is a post 6.x publisher
  5672.     if @publication is not NULL
  5673.     begin
  5674.         select @publication_id = publication_id,
  5675.                @thirdparty_flag = thirdparty_flag
  5676.             from MSpublications where
  5677.             publisher_id = @publisher_id and
  5678.             publisher_db = @publisher_db and
  5679.             publication = @publication
  5680.             
  5681.         -- Get article_id 
  5682.         if @article is not NULL and @article_id = 0
  5683.         begin
  5684.             select @article_id = article_id from MSarticles where 
  5685.                 publisher_id = @publisher_id and
  5686.                 publisher_db = @publisher_db and
  5687.                 publication_id = @publication_id and
  5688.                 article = @article
  5689.         end
  5690.         -- Check that subscription exists
  5691.         -- Only do the check for post 6x publisher
  5692.         if not exists (select * from MSsubscriptions where 
  5693.             publisher_id = @publisher_id and 
  5694.             publisher_db = @publisher_db and 
  5695.             publication_id = @publication_id and
  5696.             subscriber_id = @subscriber_id and
  5697.             subscriber_db = @subscriber_db)
  5698.         begin
  5699.             if @thirdparty_flag = 1
  5700.             begin
  5701.                 raiserror (14050, 16, -1)
  5702.                 return(1)
  5703.             end
  5704.             else
  5705.                 return (0)
  5706.         end
  5707.     end
  5708.  
  5709.     -- get the subscription type
  5710.     -- used when dropping dist agent
  5711.     select @subscription_type = subscription_type, 
  5712.         @independent_agent = independent_agent
  5713.         from MSsubscriptions where
  5714.         publisher_id = @publisher_id and
  5715.         publisher_db = @publisher_db and
  5716.         (publication_id = @publication_id or
  5717.          @publication_id is NULL) and
  5718.         (@article_id is NULL or
  5719.         article_id = @article_id) and
  5720.         (subscriber_id = @subscriber_id and
  5721.         (subscriber_db = @subscriber_db or @subscriber_id = @virtual))
  5722.  
  5723.     begin transaction
  5724.     save transaction MSdrop_subscription
  5725.  
  5726.     -- Delete the subscription 
  5727.     -- For anonymous type, delete virtual anonymous subscription also
  5728.     -- if deleting the  virtual subscription 
  5729.     -- (since there can be only one subscriber_id per article, subscriber_db doesn't matter)
  5730.     delete from MSsubscriptions where
  5731.         publisher_id = @publisher_id and
  5732.         publisher_db = @publisher_db and
  5733.         (publication_id = @publication_id or
  5734.          @publication_id is NULL) and
  5735.         (@article_id is NULL or
  5736.         article_id = @article_id) and
  5737.         ((subscriber_id = @subscriber_id and
  5738.         (subscriber_db = @subscriber_db or @subscriber_id = @virtual)) or
  5739.         -- Delete virtual anonymous subscription 
  5740.         -- if deleting virtual subscription for a anonymous publication
  5741.        (@subscriber_id = @virtual and subscriber_id = @virtual_anonymous))
  5742.  
  5743.     if @@error <> 0
  5744.     begin
  5745.         if @@trancount > 0
  5746.         begin
  5747.             rollback transaction MSdrop_subscription
  5748.             commit transaction  -- to finish off the tran we started in this proc (though 
  5749.                             -- work was rolled back to savepoint)
  5750.         end
  5751.         return 1
  5752.     end
  5753.     
  5754.     -- If it is the last subscription for the distribution agent, drop the dist agent
  5755.     if not exists (select * from MSsubscriptions    where
  5756.         publisher_id = @publisher_id and
  5757.         publisher_db = @publisher_db and
  5758.         (publication_id = @publication_id or
  5759.         @publication_id is NULL or
  5760.          @independent_agent = 0 ) and
  5761.         independent_agent = @independent_agent and
  5762.         subscriber_id = @subscriber_id and
  5763.         subscriber_db = @subscriber_db and
  5764.         subscription_type = @subscription_type)
  5765.     begin
  5766.         -- Harded coded in sp_MSadd_subscription.
  5767.         if @independent_agent = 0
  5768.             select @publication = 'ALL'
  5769.         /*
  5770.         ** Get agentid to check history record
  5771.         */
  5772.         select @id=id from MSdistribution_agents where 
  5773.         publisher_id = @publisher_id and
  5774.         publisher_db = @publisher_db and
  5775.         publication = @publication and
  5776.         subscriber_id = @subscriber_id and
  5777.         subscriber_db = @subscriber_db
  5778.  
  5779.     /*
  5780.     ** If the subscription has not yet been synced, there is no need for subscriber side cleanup 
  5781.     ** therefore no need for the last agent run.
  5782.     */
  5783.     if exists (select * from MSdistribution_history where agent_id = @id)
  5784.         select @keep_for_last_run = 0 -- default is not to do cleanup
  5785.     else 
  5786.         select @keep_for_last_run = 0
  5787.  
  5788.  
  5789.     /*
  5790.     ** Delete distribution task.
  5791.     */
  5792.         execute @retcode = dbo.sp_MSdrop_distribution_agent 
  5793.             @publisher_id = @publisher_id,
  5794.             @publisher_db = @publisher_db,
  5795.             @publication = @publication,
  5796.             @subscriber_id = @subscriber_id,
  5797.             @subscriber_db = @subscriber_db,
  5798.             @subscription_type = @subscription_type,
  5799.             @keep_for_last_run = @keep_for_last_run  
  5800.  
  5801.         if @@error <> 0 or @retcode <> 0
  5802.         begin
  5803.             if @@trancount > 0
  5804.             begin
  5805.                 rollback transaction MSdrop_subscription
  5806.                 commit transaction  -- to finish off the tran we started in this proc (though 
  5807.                                 -- work was rolled back to savepoint)
  5808.             end
  5809.             return 1
  5810.         end
  5811.     end
  5812.  
  5813.     
  5814.     -- Delete anonymous agents that are not in subscription table anymore
  5815.     -- It is due to dropping articles. Don't raise messages
  5816.     if @subscriber_id = @virtual
  5817.     begin
  5818.         delete MSdistribution_agents where
  5819.             anonymous_agent_id is not null and 
  5820.             not exists (select * from MSsubscriptions s where
  5821.                 s.agent_id = anonymous_agent_id)
  5822.  
  5823.  
  5824.         if @@error <> 0
  5825.         begin
  5826.             if @@trancount > 0
  5827.             begin
  5828.                 rollback transaction MSdrop_subscription
  5829.                 commit transaction  -- to finish off the tran we started in this proc (though 
  5830.                                 -- work was rolled back to savepoint)
  5831.             end
  5832.             return 1
  5833.         end
  5834.     end
  5835.  
  5836.  
  5837.     commit transaction
  5838.  
  5839.     --  Add dummy distribution aent row entry for publication.  This will allow the status
  5840.     --  for the shared distribution agent to be restricted
  5841.     if @publication_name IS NOT NULL
  5842.     begin
  5843.         EXEC dbo.sp_MSupdate_replication_status
  5844.             @publisher,
  5845.             @publisher_db,
  5846.             @publication_name, 
  5847.             @agent_type = 3,   
  5848.             @agent_name = NULL, 
  5849.             @status = -1    -- delete
  5850.     end
  5851.  
  5852.     -- Refresh global status table. 
  5853.     EXEC dbo.sp_MSupdate_replication_status
  5854.         @publisher,
  5855.         @publisher_db,
  5856.         @publication = '%',    -- refresh the publisher node.
  5857.         @agent_type = NULL,    -- Not used    with @status = -2
  5858.         @agent_name = NULL, -- Not used with @status = -2
  5859.         @status = -2    -- refresh status
  5860.  
  5861. GO
  5862.  
  5863. raiserror(15339,-1,-1,'sp_MSadd_subscription')
  5864. GO
  5865. CREATE PROCEDURE sp_MSadd_subscription
  5866. @publisher sysname,
  5867. @publisher_db sysname,
  5868. @subscriber sysname,       
  5869. @article_id int = NULL,
  5870. @subscriber_db sysname = NULL,
  5871. @status tinyint,                    -- 0 = inactive, 1 = subscribed, 2 = active 
  5872. @subscription_seqno varbinary(16),  -- publisher's database sequence number 
  5873.  
  5874. -- Post 6.5 parameters
  5875. @publication sysname = NULL,    -- 6.x publishers will not provide this
  5876. @article sysname = NULL,
  5877. @subscription_type tinyint = 0,     -- 0 = push, 1 = pull, 2 = anonymous 
  5878. @sync_type tinyint = 0,             -- 0 = none  1 = automatic snaphot  2 = no intial snapshot
  5879. @snapshot_seqno_flag bit = 0,       -- 1 = subscription seqno is the snapshot seqno
  5880.  
  5881. @frequency_type int = NULL,
  5882. @frequency_interval int = NULL,
  5883. @frequency_relative_interval int = NULL,
  5884. @frequency_recurrence_factor int = NULL,
  5885. @frequency_subday int = NULL,
  5886. @frequency_subday_interval int = NULL,
  5887. @active_start_time_of_day int = NULL,
  5888. @active_end_time_of_day int = NULL,
  5889. @active_start_date int = NULL,
  5890. @active_end_date int = NULL,
  5891. @optional_command_line nvarchar(4000) = '',
  5892.  
  5893. -- synctran
  5894. @update_mode tinyint = 0, -- 0 = read only, 1 = sync tran
  5895. @loopback_detection bit = 0,
  5896. @distribution_jobid binary(16) = NULL OUTPUT
  5897.  
  5898. as
  5899.  
  5900.     set nocount on
  5901.     declare @publisher_id smallint
  5902.     declare @subscriber_id smallint
  5903.     declare @command nvarchar (4000)
  5904.     declare @type tinyint
  5905.     declare @database sysname
  5906.     declare @name nvarchar (100)
  5907.     declare @long_name nvarchar (255)
  5908.     declare @retcode int
  5909.     declare @login sysname
  5910.     declare @password sysname
  5911.     declare @retryattempts int
  5912.     declare @retrydelay int
  5913.     declare @virtual smallint                       -- const: virtual subscriber id 
  5914.     declare @virtual_anonymous smallint                 -- const: virtual anonymous subscriber id 
  5915.     declare @publication_str nvarchar (32)
  5916.     declare @agent_id int
  5917.     declare @publication_id int
  5918.     declare @independent_agent bit
  5919.     declare @allow_anonymous bit
  5920.     declare @allow_pull bit
  5921.     declare @active tinyint
  5922.  
  5923.     declare @flushfrequency int 
  5924.     declare @frequencytype int
  5925.     declare @frequencyinterval int 
  5926.     declare @frequencyrelativeinterval int
  5927.     declare @frequencyrecurrencefactor int 
  5928.     declare @frequencysubday int 
  5929.     declare @frequencysubdayinterval int
  5930.     declare @activestarttimeofday int
  5931.     declare @activeendtimeofday int
  5932.     declare @activestartdate int 
  5933.     declare @activeenddate int 
  5934.     DECLARE @dsn_subscriber tinyint
  5935.     DECLARE @jet_subscriber tinyint
  5936.     DECLARE @oledb_subscriber tinyint
  5937.     declare @thirdparty_flag bit
  5938.  
  5939.     DECLARE @distributor_security_mode      int                     /* 0 standard; 1 integrated */
  5940.     DECLARE @distributor_login              sysname 
  5941.     DECLARE @distributor_password           sysname
  5942.     DECLARE @publisher_database_id int
  5943.     DECLARE @platform_nt binary
  5944.     declare @anonymous_agent_id int
  5945.     DECLARE @agent_name nvarchar(100)
  5946.     DECLARE @publication_name sysname
  5947.  
  5948.     -- Store off publication name for dummy monitor row
  5949.     select @publication_name = @publication
  5950.  
  5951.     -- Defined in sqlrepl.h
  5952.     -- Set null @optional_command_line to empty string to avoid string concat problem
  5953.     if @optional_command_line is null
  5954.         set @optional_command_line = ''
  5955.  
  5956.     select @dsn_subscriber = 1    /* Const: subscriber type 'dsn' */ 
  5957.     select @jet_subscriber = 2   
  5958.     select @oledb_subscriber = 3   
  5959.  
  5960.     select @virtual = -1
  5961.     select @virtual_anonymous = -2
  5962.  
  5963.     select @active = 2
  5964.  
  5965.     select @platform_nt = 0x1
  5966.  
  5967.     -- Check if publisher is a defined as a distribution publisher in the current database
  5968.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  5969.     if @retcode <> 0 or @@error <> 0
  5970.     begin
  5971.         return(1)
  5972.     end
  5973.  
  5974.     -- Check if subscriber exists
  5975.     if @subscriber is null
  5976.     begin
  5977.       select @subscriber_id = @virtual
  5978.       -- The following 2 variables are hardcoded in sp_MSget_repl_cmds_anonymous 
  5979.       select @subscriber_db = 'virtual'
  5980.       select @subscription_type = 0
  5981.     end
  5982.     else
  5983.         select @subscriber_id = srvid from master..sysservers, MSsubscriber_info where 
  5984.             UPPER(srvname) = UPPER(@subscriber) and
  5985.             UPPER(subscriber) = UPPER(@subscriber) and
  5986.             UPPER(publisher) = UPPER(@publisher)
  5987.     if @subscriber_id is NULL
  5988.     begin
  5989.         raiserror (20032, 16, -1, @subscriber, @publisher) 
  5990.         return (1)
  5991.     end
  5992.  
  5993.     -- Special logic for 6.5 publisher.
  5994.     -- If publisher_id, publisher_db pair is not in MSpublisher_databases then add it.  This will be used
  5995.     -- to store a publisher_database_id in the MSrepl_transactions and MSrepl_commands table.
  5996.     if @publication is null
  5997.     begin
  5998.         if not exists (select * from MSpublisher_databases where publisher_id = @publisher_id and
  5999.             publisher_db = @publisher_db)
  6000.         begin
  6001.             insert into MSpublisher_databases (publisher_id, publisher_db) values (@publisher_id, @publisher_db)
  6002.             if @@error <> 0
  6003.                 goto UNDO
  6004.         end
  6005.     end
  6006.  
  6007.     -- Get publisher_database_id
  6008.     select @publisher_database_id = id from MSpublisher_databases where publisher_id = @publisher_id and
  6009.         publisher_db = @publisher_db
  6010.     if @@error <> 0
  6011.         return 1
  6012.  
  6013.     -- If publication exists this is a post 6.x publisher
  6014.     if @publication is not NULL
  6015.     begin
  6016.         select @publication_id = publication_id, @allow_anonymous = allow_anonymous,
  6017.             @independent_agent = independent_agent, @allow_pull = allow_pull,
  6018.             @thirdparty_flag = thirdparty_flag from 
  6019.             MSpublications where 
  6020.             publisher_id = @publisher_id and
  6021.             publisher_db = @publisher_db and
  6022.             publication = @publication
  6023.         if @publication_id is NULL
  6024.         begin
  6025.             raiserror (20026, 11, -1, @publication)
  6026.             return (1)
  6027.         end
  6028.  
  6029.         -- Check if article_id exists
  6030.         if @article_id is not NULL 
  6031.         begin
  6032.             if not exists (select * from MSarticles where 
  6033.                 publisher_id = @publisher_id and
  6034.                 publisher_db = @publisher_db and
  6035.                 article_id = @article_id)
  6036.             begin
  6037.                 raiserror (20027, 11, -1, @article) 
  6038.                 return (1)
  6039.             end
  6040.         end
  6041.  
  6042.         -- Check if article exists
  6043.         if @article is not NULL and @article_id is NULL
  6044.         begin
  6045.             select @article_id = article_id from MSarticles where 
  6046.                 publisher_id = @publisher_id and
  6047.                 publisher_db = @publisher_db and
  6048.                 article = @article
  6049.             if @article_id is NULL
  6050.             begin
  6051.                 raiserror (20027, 11, -1, @article) 
  6052.                 return (1)
  6053.             end
  6054.         end
  6055.     end
  6056.     else
  6057.     begin   -- Set 6.x publishing values
  6058.         select @publication_id = 0
  6059.         select @independent_agent = 0
  6060.         select @allow_anonymous = 0
  6061.         select @allow_pull = 0
  6062.         select @thirdparty_flag = 0
  6063.     end
  6064.  
  6065.     -- Make sure subscription does not already exist
  6066.     if exists (select * from MSsubscriptions where 
  6067.         publisher_id = @publisher_id and 
  6068.         publisher_db = @publisher_db and 
  6069.         publication_id = @publication_id and
  6070.         article_id = @article_id and
  6071.         subscriber_id = @subscriber_id and
  6072.         subscriber_db = @subscriber_db)
  6073.     begin
  6074.         if @thirdparty_flag = 1
  6075.         begin
  6076.             raiserror (14058, 16, -1)
  6077.             return(1)
  6078.         end
  6079.         else
  6080.         begin
  6081.             exec @retcode = dbo.sp_MSdrop_subscription
  6082.                 @publisher = @publisher,
  6083.                 @publisher_db = @publisher_db,
  6084.                 @subscriber = @subscriber,
  6085.                 @article_id = @article_id,
  6086.                 @subscriber_db = @subscriber_db,
  6087.                 @publication = @publication,
  6088.                 @article = @article
  6089.             if @retcode <> 0 or @@error <> 0
  6090.             begin
  6091.                 return(1)
  6092.             end
  6093.         end
  6094.     end
  6095.  
  6096.     -- Check to see if we need to add a new distribution agent for the subscription.
  6097.     -- It is database wide for non independent agent publications, and publication wide otherwise.
  6098.     -- Check to see if the distribution agent for this subscription is already added.
  6099.  
  6100.     select @agent_id = NULL
  6101.     select @agent_id = agent_id from 
  6102.         MSsubscriptions where
  6103.         publisher_id = @publisher_id and
  6104.         publisher_db = @publisher_db and
  6105.         subscription_type = @subscription_type and
  6106.         (publication_id = @publication_id or @independent_agent = 0) and
  6107.         independent_agent = @independent_agent and 
  6108.         subscriber_id = @subscriber_id and
  6109.         subscriber_db = @subscriber_db
  6110.  
  6111.     if @allow_anonymous = 1 and @subscriber_id = @virtual
  6112.     begin
  6113.         select @anonymous_agent_id = agent_id from 
  6114.             MSsubscriptions where
  6115.             publisher_id = @publisher_id and
  6116.             publisher_db = @publisher_db and
  6117.             subscription_type = @subscription_type and
  6118.             (publication_id = @publication_id or @independent_agent = 0) and
  6119.             independent_agent = @independent_agent and 
  6120.             subscriber_id = @virtual_anonymous and
  6121.             subscriber_db = @subscriber_db
  6122.     end
  6123.     
  6124.     -- Always use integrated security on winNT
  6125.     if (@platform_nt = platform() & @platform_nt )
  6126.         set @distributor_security_mode = 1
  6127.     else
  6128.     begin
  6129.         select  @distributor_security_mode = 0,
  6130.                 @distributor_login  = login,
  6131.                 @distributor_password = password
  6132.             from msdb..MSdistpublishers where UPPER(name) = UPPER(@@servername)
  6133.     end
  6134.  
  6135.     begin tran
  6136.     save transaction MSadd_subscription
  6137.  
  6138.     if @agent_id is NOT NULL
  6139.     begin
  6140.         select @distribution_jobid = job_id from MSdistribution_agents
  6141.             where id = @agent_id
  6142.         /* See bug 39688
  6143.         -- Get exclusive lock on the rows for the distribution agent in the subscription table
  6144.         -- if the status of the new subscription is active.
  6145.         -- This effectively makes this sp wait for sp_MSget_repl_commands to finish.
  6146.         if @status = @active
  6147.             exec dbo.sp_MSlock_distribution_agent @agent_id
  6148.         */
  6149.     end
  6150.     else
  6151.     begin
  6152.  
  6153.  
  6154.         -- Create distribution agent
  6155.         -- Do not create local job if
  6156.         -- 1. virtual subscription 
  6157.         -- 2. no subscriber information, return (6.x legacy)
  6158.         -- 3. pull (this sp will not be called for anonymous subscription)
  6159.  
  6160.         declare @local_job bit
  6161.  
  6162.         if @subscriber_id = @virtual or 
  6163.             not exists (select * from MSsubscriber_info where
  6164.                 UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)) OR 
  6165.             @subscription_type = 1 
  6166.  
  6167.             select @local_job = 0
  6168.         else
  6169.             select @local_job = 1
  6170.  
  6171.         -- 'ALL' is reserved for indication all publications
  6172.         -- Hardcoded in sp_MSenum*... 
  6173.         -- Note! @publication is overwritten
  6174.         
  6175.         if @independent_agent = 0
  6176.             select @publication = 'ALL'
  6177.  
  6178.         if @local_job = 1
  6179.         begin
  6180.             --Get default task parameter values from MSsubscriber_info 
  6181.             select @type = type
  6182.             from MSsubscriber_info 
  6183.             where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  6184.  
  6185.             select 
  6186.                 @frequencytype = frequency_type,
  6187.                 @frequencyinterval = frequency_interval,
  6188.                 @frequencyrelativeinterval = frequency_relative_interval,
  6189.                 @frequencyrecurrencefactor = frequency_recurrence_factor,
  6190.                 @frequencysubday = frequency_subday,
  6191.                 @frequencysubdayinterval = frequency_subday_interval,
  6192.                 @activestarttimeofday = active_start_time_of_day,
  6193.                 @activeendtimeofday = active_end_time_of_day,
  6194.                 @activestartdate = active_start_date,
  6195.                 @activeenddate = active_end_date
  6196.             from MSsubscriber_schedule 
  6197.             where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0    
  6198.  
  6199.             if @frequency_type is null
  6200.                 select @frequency_type = @frequencytype
  6201.  
  6202.             if @frequency_interval  is null
  6203.                 select  @frequency_interval = @frequencyinterval
  6204.  
  6205.             if @frequency_relative_interval is null
  6206.                 select  @frequency_relative_interval = @frequencyrelativeinterval
  6207.  
  6208.             if @frequency_recurrence_factor is null
  6209.                 select  @frequency_recurrence_factor = @frequencyrecurrencefactor
  6210.  
  6211.             if @frequency_subday is null
  6212.                 select  @frequency_subday = @frequencysubday
  6213.  
  6214.             if @frequency_subday_interval is null
  6215.                 select  @frequency_subday_interval = @frequencysubdayinterval
  6216.  
  6217.             if @active_start_time_of_day is null
  6218.                 select  @active_start_time_of_day = @activestarttimeofday
  6219.  
  6220.             if @active_end_time_of_day is null
  6221.                 select  @active_end_time_of_day = @activeendtimeofday
  6222.  
  6223.             if @active_start_date is null
  6224.                 select  @active_start_date = @activestartdate
  6225.  
  6226.             if @active_end_date is null
  6227.                 select  @active_end_date = @activeenddate
  6228.  
  6229.             -- Construct task command 
  6230.             select @command = '-Subscriber ' + QUOTENAME(@subscriber)  + ' '
  6231.  
  6232.             -- DSN subscribers don't have a subscriber db name.
  6233.             if @subscriber_db is not NULL AND @type <> @dsn_subscriber 
  6234.                 AND @type <> @jet_subscriber AND @type <> @oledb_subscriber
  6235.                 select @command = @command  + '-SubscriberDB ' + QUOTENAME(@subscriber_db) + ' '
  6236.             select @command = @command + '-Publisher ' + QUOTENAME(@publisher) + ' '
  6237.             select @command = @command + '-Distributor ' + @@SERVERNAME + ' '
  6238.  
  6239.             select @command = @command + '-DistributorSecurityMode ' + 
  6240.                 convert(nvarchar(10),@distributor_security_mode) +  ' ' 
  6241.             if @distributor_security_mode <> 1
  6242.             begin
  6243.                 if @distributor_login is not NULL
  6244.                     select @command = @command + '-DistributorLogin ' + @distributor_login + ' '
  6245.                 if @distributor_password is not NULL
  6246.                     select @command = @command + '-DistributorEncryptedPassword ' + quotename(@distributor_password) + ' '
  6247.             end
  6248.  
  6249.             if @independent_agent = 1
  6250.                 select @command = @command +'-Publication ' + QUOTENAME(@publication) + ' '
  6251.  
  6252.             if @publisher_db is not NULL
  6253.                 select @command = @command + '-PublisherDB ' + QUOTENAME(@publisher_db) + ' '
  6254.  
  6255.             if @type = @dsn_subscriber or @type = @oledb_subscriber
  6256.               select @command = @command + '-SubscriberType ' + convert (nvarchar(10),@type) + ' '
  6257.  
  6258.             -- 64 is auto-start. Agents should be in continuous mode. sp_MSadd_repl_job will append "-Continuous" to the end of command line
  6259.  
  6260.             if datalength(@command) + datalength(@optional_command_line) > 8000
  6261.             begin
  6262.                 RAISERROR(20018, 16, -1)
  6263.                 RETURN(1)
  6264.             end
  6265.             select @command = @command + @optional_command_line
  6266.             
  6267.             execute @retcode = dbo.sp_MSadd_distribution_agent
  6268.                 @publisher_id = @publisher_id,
  6269.                 @publisher_db = @publisher_db,
  6270.                 @publication = @publication,
  6271.                 @subscriber_id = @subscriber_id,
  6272.                 @subscriber_db = @subscriber_db,
  6273.                 @subscription_type = @subscription_type,
  6274.                 @local_job = @local_job,
  6275.                 @frequency_type = @frequency_type,
  6276.                 @frequency_interval = @frequency_interval,
  6277.                 @frequency_subday = @frequency_subday,
  6278.                 @frequency_subday_interval = @frequency_subday_interval,
  6279.                 @frequency_relative_interval = @frequency_relative_interval,
  6280.                 @frequency_recurrence_factor = @frequency_recurrence_factor,
  6281.                 @active_start_date = @active_start_date,
  6282.                 @active_end_date = @active_end_date,
  6283.                 @active_start_time_of_day = @active_start_time_of_day,
  6284.                 @active_end_time_of_day = @active_end_time_of_day,
  6285.                 @command = @command,
  6286.                 @agent_id = @agent_id OUTPUT,
  6287.                 @distribution_jobid = @distribution_jobid OUTPUT
  6288.  
  6289.             if @@error <> 0 or @retcode <> 0
  6290.                 goto UNDO
  6291.         end
  6292.         else
  6293.         begin
  6294.             execute @retcode = dbo.sp_MSadd_distribution_agent
  6295.                 @publisher_id = @publisher_id,
  6296.                 @publisher_db = @publisher_db,
  6297.                 @publication = @publication,
  6298.                 @subscriber_id = @subscriber_id,
  6299.                 @subscriber_db = @subscriber_db,
  6300.                 @subscription_type = @subscription_type,
  6301.                 @local_job = @local_job,
  6302.                 @agent_id = @agent_id OUTPUT,
  6303.                 @distribution_jobid = @distribution_jobid OUTPUT
  6304.  
  6305.             if @@error <> 0 or @retcode <> 0
  6306.                 goto UNDO
  6307.         end
  6308.  
  6309.         if @allow_anonymous = 1 and @subscriber_id = @virtual
  6310.         begin
  6311.             execute @retcode = dbo.sp_MSadd_distribution_agent
  6312.                 @publisher_id = @publisher_id,
  6313.                 @publisher_db = @publisher_db,
  6314.                 @publication = @publication,
  6315.                 @subscriber_id = @virtual_anonymous,
  6316.                 @subscriber_db = @subscriber_db,
  6317.                 @subscription_type = @subscription_type,
  6318.                 @local_job = @local_job,
  6319.                 @agent_id = @anonymous_agent_id OUTPUT,
  6320.                 @distribution_jobid = @distribution_jobid OUTPUT
  6321.         end
  6322.     end
  6323.  
  6324.     insert into MSsubscriptions values (@publisher_database_id, @publisher_id, @publisher_db, @publication_id,
  6325.         @article_id, @subscriber_id, @subscriber_db, @subscription_type, @sync_type, @status, 
  6326.         @subscription_seqno, @snapshot_seqno_flag, @independent_agent, getdate(), 
  6327.         -- synctran
  6328.         @loopback_detection, @agent_id, @update_mode, @subscription_seqno)
  6329.     if @@error <> 0
  6330.         goto UNDO
  6331.  
  6332.     -- If anonymous publication, add "virtual anonymous" subscription
  6333.     -- when adding the virtual subscription
  6334.     if @allow_anonymous = 1 and @subscriber_id = @virtual
  6335.     begin
  6336.         insert into MSsubscriptions values (@publisher_database_id, @publisher_id, @publisher_db, @publication_id,
  6337.             @article_id, @virtual_anonymous, @subscriber_db, @subscription_type, @sync_type, @status, 
  6338.             @subscription_seqno, @snapshot_seqno_flag, @independent_agent, getdate(), 
  6339.             -- synctran
  6340.             @loopback_detection, @anonymous_agent_id, @update_mode, @subscription_seqno)
  6341.         if @@error <> 0
  6342.             goto UNDO
  6343.     end
  6344.  
  6345.     commit transaction
  6346.  
  6347.     --  Add dummy distribution aent row entry for publication.  This will allow the status
  6348.     --  for the shared distribution agent to be restricted
  6349.     if @publication_name IS NOT NULL
  6350.     begin
  6351.         select @agent_name = name from MSdistribution_agents where id = @agent_id
  6352.  
  6353.         if @agent_name IS NOT NULL
  6354.             EXEC dbo.sp_MSupdate_replication_status
  6355.                 @publisher,
  6356.                 @publisher_db,
  6357.                 @publication_name, 
  6358.                 @agent_type = 3,   
  6359.                 @agent_name = @agent_name, 
  6360.                 @status = -3    -- Use current agent_status
  6361.     end
  6362.  
  6363.     -- Refresh global status table. 
  6364.     EXEC dbo.sp_MSupdate_replication_status
  6365.         @publisher,
  6366.         @publisher_db,
  6367.         @publication = '%',    -- refresh the publisher node.
  6368.         @agent_type = NULL,    -- Not used    with @status = -2
  6369.         @agent_name = NULL, -- Not used with @status = -2
  6370.         @status = -2    -- refresh status
  6371.  
  6372.     return(0)
  6373.  
  6374. UNDO:
  6375.     if @@TRANCOUNT > 0
  6376.     begin
  6377.         ROLLBACK TRAN MSadd_subscription
  6378.         COMMIT TRAN
  6379.     end
  6380.     return(1)
  6381.  
  6382. GO
  6383.  
  6384. raiserror(15339,-1,-1,'sp_MSupdate_subscription')
  6385. GO
  6386. CREATE PROCEDURE sp_MSupdate_subscription
  6387. @publisher sysname,
  6388. @publisher_db sysname,
  6389. @subscriber sysname,
  6390. @article_id int,
  6391. @status int,
  6392. @subscription_seqno varbinary(16),
  6393. --post 6x
  6394. @destination_db sysname = '%'
  6395.  
  6396. as
  6397.     set nocount on
  6398.     declare @publisher_id smallint  
  6399.     declare @subscriber_id smallint
  6400.     declare @automatic tinyint
  6401.     declare @snapshot_seqno_flag bit
  6402.     declare @virtual smallint 
  6403.     declare @virtual_anonymous smallint 
  6404.     declare @retcode int
  6405.     declare @active tinyint
  6406.     declare @subscribed tinyint
  6407.     declare @agent_id int
  6408.     declare @sync_type tinyint
  6409.     declare @virtual_agent_id int
  6410.     declare @publication_id int
  6411.  
  6412.     select @automatic = 1
  6413.     select @virtual = - 1
  6414.     select @virtual_anonymous = - 2
  6415.     select @active = 2
  6416.     select @subscribed = 1
  6417.  
  6418.     -- Check if publisher is a defined as a distribution publisher in the current database
  6419.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  6420.     if @retcode <> 0
  6421.     begin
  6422.         return(1)
  6423.     end
  6424.  
  6425.     -- Check if subscriber exists
  6426.     if @subscriber is null
  6427.     begin
  6428.         select @subscriber_id = @virtual
  6429.         select @destination_db = '%'
  6430.     end
  6431.     else
  6432.         select @subscriber_id = srvid from master..sysservers, MSsubscriber_info where 
  6433.             UPPER(srvname) = UPPER(@subscriber) and
  6434.             UPPER(subscriber) = UPPER(@subscriber) and
  6435.             UPPER(publisher) = UPPER(@publisher)
  6436.     if @subscriber_id is NULL
  6437.     begin
  6438.         raiserror (20032, 16, -1, @subscriber, @publisher) 
  6439.         return (1)
  6440.     end
  6441.  
  6442.     begin tran
  6443.     save transaction MSupdate_subscription
  6444.  
  6445.     if @status = @active
  6446.     begin
  6447.         -- Activating the subscription
  6448.         /*
  6449.         **  It will be used by:
  6450.         **  1. no_sync subscriptions
  6451.         **  2. subscriptions on immediate_sync pub that are activate 
  6452.         **  using virtual subscritpions's snapshots.
  6453.         **  3. snapshot agents for 6.5 publishers
  6454.         */
  6455.         -- Get agent_id etc
  6456.         select @agent_id = agent_id, @sync_type = sync_type,
  6457.             @publication_id = publication_id
  6458.             from MSsubscriptions where
  6459.             publisher_id = @publisher_id and
  6460.             publisher_db = @publisher_db and
  6461.             article_id = @article_id and
  6462.             subscriber_id = @subscriber_id and 
  6463.             -- Use equal so 6.x publisher will get nothing (since @destination_db is '%')
  6464.             subscriber_db = @destination_db
  6465.  
  6466.         -- If immediate_sync publication and sync type is auto_sync
  6467.         -- Set the subscription_seqno and snapshot_seqno to be of the virtual subscription 
  6468.         -- for real subscription when activating the subscription.
  6469.         -- We have to do it for the whole publication to prevent the
  6470.         -- distribution agent from picking up partial snapshot transaction
  6471.         if  @subscriber IS NOT NULL AND
  6472.             @sync_type = @automatic and
  6473.             exists (select * from MSpublications p where
  6474.                 -- publication_id is unique across dist db
  6475.                 p.publication_id = @publication_id and
  6476.                 p.immediate_sync = 1 
  6477.                 )
  6478.         begin
  6479.             -- Get virtual agent_id
  6480.             select @virtual_agent_id = agent_id from MSsubscriptions where
  6481.                 publisher_id = @publisher_id and
  6482.                 publisher_db = @publisher_db and
  6483.                 article_id = @article_id and
  6484.                 subscriber_id = @virtual
  6485.  
  6486.             -- Note it is possible that the virtual subscriptions
  6487.             -- were deactivated during clean up.
  6488.             /* Update the subscription table for the whole publication */
  6489.             update MSsubscriptions  set 
  6490.                 snapshot_seqno_flag =  
  6491.                     (select subscription_seqno from MSsubscriptions rs2
  6492.                         where
  6493.                         rs2.agent_id = @virtual_agent_id and
  6494.                         rs2.article_id = rs1.article_id),
  6495.                 status =    
  6496.                     (select status from MSsubscriptions rs2
  6497.                         where
  6498.                         rs2.agent_id = @virtual_agent_id and
  6499.                         rs2.article_id = rs1.article_id),
  6500.                 -- Use current date rather than virtual sub date for the
  6501.                 -- calculation in cleanup 
  6502.                 subscription_time = getdate(),
  6503.                 subscription_seqno = 
  6504.                     (select subscription_seqno from MSsubscriptions rs2
  6505.                         where
  6506.                         rs2.agent_id = @virtual_agent_id and
  6507.                         rs2.article_id = rs1.article_id),
  6508.                 publisher_seqno = 
  6509.                     (select publisher_seqno from MSsubscriptions rs2
  6510.                         where
  6511.                         rs2.agent_id = @virtual_agent_id and
  6512.                         rs2.article_id = rs1.article_id)
  6513.                 from MSsubscriptions rs1 where
  6514.                     agent_id = @agent_id and
  6515.                     sync_type = @automatic and
  6516.                     status = @subscribed            
  6517.             if @@ERROR <> 0
  6518.                 goto UNDO
  6519.         end
  6520.         else
  6521.         begin
  6522.             update MSsubscriptions set status = @status, subscription_time = getdate(), 
  6523.                 publisher_seqno = @subscription_seqno,
  6524.                 -- Have to do this. Refer to anonymous agent "no init sync" option logic above
  6525.                 -- and sp_MSset_snapshot_seqno.
  6526.                 snapshot_seqno_flag = 0 
  6527.                 where
  6528.                   publisher_id = @publisher_id and
  6529.                   publisher_db = @publisher_db and
  6530.                   article_id = @article_id and
  6531.                   ((@subscriber_id <> @virtual and (subscriber_id = @subscriber_id and subscriber_db LIKE @destination_db)) or
  6532.                   -- Activate virtual_anonymous but NOT virtual
  6533.                   -- This is for no init option for anonymous agent
  6534.                   -- Refer to sp_addsubscription , sp_MSget_repl_cmds_anonymous
  6535.                   -- and sp_MSset_snapshot_seqno
  6536.                   (@subscriber_id =  @virtual and subscriber_id = @virtual_anonymous))
  6537.             if @@error <> 0
  6538.                 goto UNDO
  6539.         
  6540.             -- For 6.5 publishers.
  6541.             -- Snapshot agents of 6.5 publishers will call sp_changesubstatus which will
  6542.             -- RPC this stored procedure to activate the subscription. The RPC calls are
  6543.             -- not in one transaction.
  6544.             -- We have to do it for the whole publication to prevent the
  6545.             -- distribution agent from picking up partial snapshot transaction
  6546.  
  6547.             -- Get publication_id 
  6548.             -- The publication_id and sync type are set by SNAPSHOT agent 
  6549.             -- calling sp_MSset_snapshot_xact_seqno
  6550.             -- Don't do it if @subscriber_id is virtual to prevent virtual sub
  6551.             -- to be activated.
  6552.             if @destination_db = '%'
  6553.             begin
  6554.                 declare @publication_id_6x int
  6555.                 -- Get the publication_id.
  6556.                 -- Note that if the sync_type is not automatic, the publication_id
  6557.                 -- will be null. In this case, we will not do the later
  6558.                 -- update (we don't need to)
  6559.                 select top 1 @publication_id_6x = publication_id from MSsubscriptions 
  6560.                     where   publisher_id = @publisher_id and
  6561.                             publisher_db = @publisher_db and
  6562.                             subscriber_id = @subscriber_id and 
  6563.                             --subscriber_db LIKE @destination_db and
  6564.                             sync_type = @automatic and
  6565.                             article_id = @article_id
  6566.  
  6567.                 if @publication_id_6x <> NULL
  6568.                 begin
  6569.                     update MSsubscriptions set status = @status, subscription_time = getdate() 
  6570.                         where
  6571.                           publisher_id = @publisher_id and
  6572.                           publisher_db = @publisher_db and
  6573.                           subscriber_id = @subscriber_id and 
  6574.                           --subscriber_db LIKE @destination_db and
  6575.                           sync_type = @automatic and
  6576.                           publication_id = @publication_id_6x and
  6577.                           status <> @status
  6578.                     if @@error <> 0
  6579.                         goto UNDO
  6580.                 end
  6581.             end
  6582.         end
  6583.     end -- End activating the subscription
  6584.     else
  6585.     begin -- Deactivating the subscription
  6586.         /*
  6587.         **  It will be used by:
  6588.         **  sp_reinitsubscription at publisher to reset the subscription status to 'subscribed'
  6589.         */
  6590.  
  6591.         update MSsubscriptions set status = @status, publisher_seqno = @subscription_seqno
  6592.             where
  6593.             publisher_id = @publisher_id and
  6594.             publisher_db = @publisher_db and
  6595.             article_id = @article_id and
  6596.             ((@subscriber_id <> @virtual and (subscriber_id = @subscriber_id and subscriber_db LIKE @destination_db)) or
  6597.             -- Deactivating both virtual and virtual anonymous
  6598.             (@subscriber_id =  @virtual and (subscriber_id = @virtual or subscriber_id = @virtual_anonymous))) 
  6599.  
  6600.         if @@error <> 0
  6601.             goto UNDO
  6602.     end
  6603.  
  6604.     
  6605.     commit transaction
  6606.     return (0)
  6607.  
  6608. UNDO:
  6609.     if @@TRANCOUNT > 0
  6610.     begin
  6611.         ROLLBACK TRAN MSupdate_subscription
  6612.         COMMIT TRAN
  6613.     end
  6614.     return(1)
  6615. GO
  6616.  
  6617.  
  6618. declare @dbname sysname
  6619. select  @dbname = db_name()
  6620. execute('dump transaction ' +@dbname+ ' with no_log')
  6621.  
  6622. go
  6623.  
  6624. /*
  6625. **  Note: sp_MSget_repl_commands and sp_MSget_repl_count have very similar
  6626. **  queries. Any changes to one of them should be applied to all others.
  6627. */
  6628.  
  6629. raiserror(15339,-1,-1,'sp_MSget_repl_commands')
  6630. GO
  6631. CREATE PROCEDURE sp_MSget_repl_commands
  6632. @agent_id int,
  6633. @last_xact_seqno varbinary(16),
  6634. @get_count bit = 0
  6635. as
  6636.  
  6637.     set nocount on
  6638.  
  6639.     declare @active_status tinyint
  6640.     declare @snapshot_bit int
  6641.     declare @synctran_type int
  6642.     declare @synctran tinyint
  6643.     declare @retcode int
  6644.     declare @publisher_database_id int
  6645.     declare @originator_id int
  6646.     declare @subscriber sysname
  6647.     declare @subscriber_db sysname
  6648.     declare @subscriber_id smallint
  6649.     declare @publisher_db sysname
  6650.     declare @publisher_id smallint
  6651.     declare @max_xact_seqno varbinary(16)
  6652.  
  6653.     select @synctran = 1
  6654.     select @active_status = 2
  6655.     select @snapshot_bit = 0x80000000
  6656.     -- in sqlrepl.h
  6657.     select @synctran_type = @snapshot_bit | 9
  6658.     
  6659.  
  6660.     -- Security Check
  6661.     -- @agent_id might be null when it comes from sp_MSget_repl_cmd_anonymous
  6662.     if @agent_id is not null
  6663.     begin
  6664.         exec @retcode = dbo.sp_MScheck_pull_access
  6665.             @agent_id = @agent_id,
  6666.             @agent_type = 0 -- distribution agent
  6667.         if @@error <> 0 or @retcode <> 0
  6668.             return (1)
  6669.     end
  6670.     
  6671.     -- Get publisher database id etc.
  6672.     SELECT @publisher_database_id = publisher_database_id,
  6673.         @publisher_db = publisher_db,
  6674.         @publisher_id = publisher_id,
  6675.         @subscriber_id = subscriber_id, @subscriber_db = subscriber_db
  6676.         from MSdistribution_agents where id = @agent_id
  6677.  
  6678.     -- Get the last xact_seqno on the pub db FIRST. It will
  6679.     -- be used as the upper bound for differnt queries. We have to do
  6680.     -- this to prevent transactions on new or changed subscriptions or
  6681.     -- with new orignator_id being skipped eigher by preselected query or
  6682.     -- preselected originator_id.
  6683.     -- Have to have readpast here to prevent the query be blocked by logreader
  6684.     -- (even before the first row to the dist agent).
  6685.     select @max_xact_seqno = max(xact_seqno) from MSrepl_commands (READPAST)
  6686.       where 
  6687.          publisher_database_id = @publisher_database_id
  6688.     -- If there's nothing to do, return here to avoid more queries.
  6689.     if @max_xact_seqno = @last_xact_seqno
  6690.     begin
  6691.         if @get_count = 1
  6692.         begin
  6693.             select 
  6694.                 'undelivered_commands' = convert(int, 0), 
  6695.                 'undelivered_transactions' = convert(int, 0) 
  6696.         end
  6697.         else
  6698.         begin
  6699.             select rc.xact_seqno, rc.partial_command, rc.type, 
  6700.                 rc.command_id, rc.command
  6701.                 from                
  6702.                     MSrepl_commands rc
  6703.                 where 0 = 1
  6704.             select @max_xact_seqno
  6705.         end
  6706.         return 0
  6707.     end
  6708.  
  6709.     -- Get subscriber name
  6710.     select @subscriber = srvname from master..sysservers where
  6711.         srvid = @subscriber_id
  6712.         
  6713.     -- Note: if no originator id in the table, it will be 0, so that no loop back
  6714.     -- detection will be done!.
  6715.     -- Since the logreader will insert into the MSrepl_originators table,
  6716.     -- this query has to be later then get max seqno query!!!!!
  6717.     select @originator_id = 0
  6718.     select @originator_id = id from MSrepl_originators where
  6719.         publisher_database_id = @publisher_database_id and
  6720.         UPPER(srvname) = UPPER(@subscriber) and
  6721.         dbname = @subscriber_db
  6722.  
  6723.         /* see bug 39688
  6724.         begin tran
  6725.         -- Get shared lock so that the subscriptions can not be changed in this transaction.
  6726.        exec dbo.sp_MSlock_distribution_agent @agent_id, @shared
  6727.        */
  6728.  
  6729.     if @get_count = 1
  6730.     begin
  6731.         select 
  6732.             'undelivered_commands' = count(*), 
  6733.             'undelivered_transactions' = count(distinct xact_seqno) from
  6734.  
  6735.         MSrepl_commands rc JOIN MSsubscriptions s
  6736.         ON (rc.article_id = s.article_id AND rc.publisher_database_id=s.publisher_database_id )
  6737.         
  6738.         where
  6739.  
  6740.         s.agent_id = @agent_id and
  6741.         s.status = @active_status and
  6742.         rc.publisher_database_id = @publisher_database_id and
  6743.         s.publisher_database_id = @publisher_database_id and
  6744.         rc.xact_seqno > @last_xact_seqno and
  6745.         rc.xact_seqno <= @max_xact_seqno and
  6746.         -- If log based transaction, we do
  6747.         -- 1. only select tran later than sub pub seqno
  6748.         -- 2. loopback detection
  6749.         (((rc.type & @snapshot_bit) <> @snapshot_bit and
  6750.         rc.xact_seqno > s.publisher_seqno and
  6751.         --
  6752.         -- Loopback detection
  6753.         --
  6754.         (@originator_id = 0 or (s.loopback_detection = 0 or
  6755.             rc.originator_id <> @originator_id))) or 
  6756.         -- If snapshot transaction, we do
  6757.         -- 1. filter out the  snapshot transactions that were inserted later that is not
  6758.         -- the subscription's snapshot transaction
  6759.         -- 2. filter out trigger generation command for non synctran subscription.
  6760.         -- Note: don't do loop back detection.
  6761.         ((rc.type & @snapshot_bit) = @snapshot_bit and 
  6762.         rc.xact_seqno = s.subscription_seqno and 
  6763.         (s.update_mode = @synctran or rc.type <> @synctran_type)))
  6764.         return(0)
  6765.     end
  6766.  
  6767.     -- Decide on a best query method.
  6768.     -- Note: The order of the following queries is important and
  6769.     -- not abitrary.
  6770.     
  6771.     -- Get subscription info
  6772.     declare @num_non_active int
  6773.     declare @num_article int
  6774.     declare @num_loopback int
  6775.     declare @max_sub_seqno varbinary(16)
  6776.     declare @max_pub_seqno varbinary(16)
  6777.  
  6778.  
  6779.     select 
  6780.         @num_non_active = sum(case when status <> @active_status then 1 else 0 end),
  6781.         @num_article = count(*),
  6782.         @num_loopback   = sum(case when loopback_detection <> 0 then 1 else 0 end),
  6783.         @max_sub_seqno  = max(subscription_seqno),
  6784.         @max_pub_seqno = max(publisher_seqno)
  6785.         from MSsubscriptions where
  6786.             agent_id = @agent_id
  6787.  
  6788.     --select @num_non_active, @num_loopback, @max_sub_seqno
  6789.     
  6790.     if  @last_xact_seqno < @max_sub_seqno or  
  6791.         @last_xact_seqno < @max_pub_seqno or 
  6792.         @num_non_active <> 0
  6793.     -- The agent is still woring on snapshot transactions. Need a full join in this case
  6794.     begin
  6795.         -- no loopback
  6796.         if @originator_id = 0
  6797.         begin
  6798.             -- Join with every thing but no loop back
  6799.             select rc.xact_seqno, rc.partial_command, rc.type, 
  6800.                 rc.command_id, rc.command
  6801.                 from                
  6802.                     MSrepl_commands rc JOIN MSsubscriptions s
  6803.                 -- At end, we use the FASTFIRSTROW option which tends to force
  6804.                 -- a nested inner loop join driven from MSrepl_commands
  6805.                 ON (rc.article_id = s.article_id AND rc.publisher_database_id=s.publisher_database_id )
  6806.                 
  6807.                 where
  6808.  
  6809.                 s.agent_id = @agent_id and
  6810.                 s.status = @active_status and
  6811.                 rc.publisher_database_id = @publisher_database_id and
  6812.                 s.publisher_database_id = @publisher_database_id and
  6813.                 rc.xact_seqno > @last_xact_seqno and
  6814.                 rc.xact_seqno <= @max_xact_seqno and
  6815.                 -- If log based transaction, we do
  6816.                 -- 1. only select tran later than sub pub seqno
  6817.                 (((rc.type & @snapshot_bit) <> @snapshot_bit and
  6818.                 rc.xact_seqno > s.publisher_seqno) or 
  6819.                 -- If snapshot transaction, we do
  6820.                 -- 1. filter out the  snapshot transactions that were inserted later that is not
  6821.                 -- the subscription's snapshot transaction
  6822.                 -- 2. filter out trigger generation command for non synctran subscription.
  6823.                 -- Note: don't do loop back detection.
  6824.                 ((rc.type & @snapshot_bit) = @snapshot_bit and 
  6825.                 rc.xact_seqno = s.subscription_seqno and 
  6826.                 (s.update_mode = @synctran or rc.type <> @synctran_type)))
  6827.                 order by rc.xact_seqno, rc.command_id asc
  6828.                 OPTION (FAST 1)
  6829.         end
  6830.         else
  6831.         begin
  6832.             -- Join with every thing with loop back
  6833.             select rc.xact_seqno, rc.partial_command, rc.type, 
  6834.                 rc.command_id, rc.command
  6835.                 from                
  6836.                     MSrepl_commands rc JOIN MSsubscriptions s
  6837.                 -- At end, we use the FASTFIRSTROW option which tends to force
  6838.                 -- a nested inner loop join driven from MSrepl_commands
  6839.                 ON (rc.article_id = s.article_id AND rc.publisher_database_id=s.publisher_database_id )
  6840.                 
  6841.                 where
  6842.  
  6843.                 s.agent_id = @agent_id and
  6844.                 s.status = @active_status and
  6845.                 rc.publisher_database_id = @publisher_database_id and
  6846.                 s.publisher_database_id = @publisher_database_id and
  6847.                 rc.xact_seqno > @last_xact_seqno and
  6848.                 rc.xact_seqno <= @max_xact_seqno and
  6849.                 -- If log based transaction, we do
  6850.                 -- 1. only select tran later than sub pub seqno
  6851.                 -- 2. loopback detection
  6852.                 (((rc.type & @snapshot_bit) <> @snapshot_bit and
  6853.                 rc.xact_seqno > s.publisher_seqno and
  6854.                 --
  6855.                 -- Loopback detection
  6856.                 --
  6857.                 (s.loopback_detection = 0 or
  6858.                     rc.originator_id <> @originator_id)) or 
  6859.                 -- If snapshot transaction, we do
  6860.                 -- 1. filter out the  snapshot transactions that were inserted later that is not
  6861.                 -- the subscription's snapshot transaction
  6862.                 -- 2. filter out trigger generation command for non synctran subscription.
  6863.                 -- Note: don't do loop back detection.
  6864.                 ((rc.type & @snapshot_bit) = @snapshot_bit and 
  6865.                 rc.xact_seqno = s.subscription_seqno and 
  6866.                 (s.update_mode = @synctran or rc.type <> @synctran_type)))
  6867.                 order by rc.xact_seqno, rc.command_id asc
  6868.                 OPTION (FAST 1)
  6869.             end
  6870.     end
  6871.     -- The agent has finished snapshot transactions but it has loopback detection.
  6872.     else if @num_loopback <> 0 and @originator_id <> 0
  6873.     begin
  6874.         -- Join plus loopback
  6875.         select rc.xact_seqno, rc.partial_command, rc.type, 
  6876.             rc.command_id, rc.command
  6877.             from                
  6878.                 MSrepl_commands rc JOIN MSsubscriptions s
  6879.             -- At end, we use the FASTFIRSTROW option which tends to force
  6880.             -- a nested inner loop join driven from MSrepl_commands
  6881.             ON (rc.article_id = s.article_id)
  6882.             
  6883.             where
  6884.  
  6885.             s.agent_id = @agent_id and
  6886.             rc.publisher_database_id = @publisher_database_id and
  6887.             rc.xact_seqno > @last_xact_seqno and
  6888.             rc.xact_seqno <= @max_xact_seqno and
  6889.             (rc.type & @snapshot_bit) <> @snapshot_bit and
  6890.             --
  6891.             -- Loopback detection
  6892.             --
  6893.             (s.loopback_detection = 0 or
  6894.             rc.originator_id <> @originator_id) 
  6895.             order by rc.xact_seqno, rc.command_id asc
  6896.             OPTION (FAST 1)
  6897.     end
  6898.     -- The agent has finished snapshot transactions. It has NO loopback detection.
  6899.     else if @num_article <> (select count(*) from MSarticles  a where
  6900.         publisher_id = @publisher_id and
  6901.         publisher_db = @publisher_db)
  6902.     -- Not a full subscription, do mini join
  6903.     begin
  6904.         -- Mini join along. Only agent_id and article_id columns in MSsubscriptions
  6905.         -- are used. So only index pages are needed for the join.
  6906.         select rc.xact_seqno, rc.partial_command, rc.type, 
  6907.         rc.command_id, rc.command
  6908.         from                
  6909.             MSrepl_commands rc JOIN MSsubscriptions s
  6910.         -- At end, we use the FASTFIRSTROW option which tends to force
  6911.         -- a nested inner loop join driven from MSrepl_commands
  6912.         ON (rc.article_id = s.article_id)
  6913.         where
  6914.         s.agent_id = @agent_id and
  6915.         rc.publisher_database_id = @publisher_database_id and
  6916.         rc.xact_seqno > @last_xact_seqno and
  6917.         rc.xact_seqno <= @max_xact_seqno and
  6918.         (rc.type & @snapshot_bit) <> @snapshot_bit
  6919.         order by rc.xact_seqno, rc.command_id asc
  6920.         OPTION (FAST 1)
  6921.     end
  6922.     else
  6923.     -- The query will fly if we reach here!! No join is needed.
  6924.     -- It is a full sub to pub db, the dist agent is beyond snapshots, 
  6925.     -- all sub are active and no loopback detection. 
  6926.     begin
  6927.         -- no join.
  6928.         select rc.xact_seqno, rc.partial_command, rc.type, 
  6929.         rc.command_id, rc.command
  6930.         from                
  6931.             MSrepl_commands rc 
  6932.         where
  6933.         rc.publisher_database_id = @publisher_database_id and
  6934.         rc.xact_seqno > @last_xact_seqno and
  6935.         rc.xact_seqno <= @max_xact_seqno and
  6936.         (rc.type & @snapshot_bit) <> @snapshot_bit 
  6937.  
  6938.         order by rc.xact_seqno, rc.command_id asc
  6939.     end 
  6940.  
  6941.     -- Return the max seqno of this batch to distribution agent.
  6942.     select @max_xact_seqno
  6943.  
  6944. GO
  6945.  
  6946.  
  6947.  
  6948. raiserror(15339,-1,-1,'sp_MSget_repl_cmds_anonymous')
  6949. GO
  6950. CREATE PROCEDURE sp_MSget_repl_cmds_anonymous
  6951. @agent_id int,
  6952. @last_xact_seqno varbinary(16),
  6953. @no_init_sync bit = 0,
  6954. @get_count bit = 0
  6955.  
  6956. as
  6957.  
  6958.    set nocount on
  6959.  
  6960.    declare @virtual_agent_id int    /* virtual sub agent id */
  6961.    declare @anonymous_agent_id int  /* virtual anonymous agent id */
  6962.  
  6963.     -- Note @agent_id will be overwritten later.
  6964.     select  @virtual_agent_id =   virtual_agent_id,
  6965.             @anonymous_agent_id = anonymous_agent_id
  6966.         from MSdistribution_agents where
  6967.             id = @agent_id
  6968.     
  6969.     -- Return error if agent entry does not exists (being deleted).
  6970.     if @virtual_agent_id is null
  6971.     begin
  6972.         raiserror(21072, 16, -1)
  6973.         return(1)
  6974.     end
  6975.  
  6976.     -- If no init sync, use anonymous account to start immediately.
  6977.     -- If first time, or still working on the first snapshot, or just finished
  6978.     -- the first snapshot, use virtual account. This is to cover the case
  6979.     -- of multiple snapshot transactions (for example, one per article) in the first
  6980.     -- snapshot.
  6981.     -- otherwise use virtual anonymous account
  6982.     if  @no_init_sync = 1 
  6983.         select @agent_id = @anonymous_agent_id
  6984.     else if @last_xact_seqno = 0x00 or
  6985.         exists (select * from MSsubscriptions where
  6986.             agent_id = @virtual_agent_id and
  6987.             subscription_seqno = @last_xact_seqno)
  6988.         select @agent_id = @virtual_agent_id
  6989.     else
  6990.         select @agent_id = @anonymous_agent_id
  6991.     -- Call main procedure to get commands
  6992.     exec dbo.sp_MSget_repl_commands 
  6993.         @agent_id = @agent_id,
  6994.         @last_xact_seqno = @last_xact_seqno,
  6995.         @get_count = @get_count
  6996. GO
  6997.  
  6998.  
  6999.  
  7000. raiserror(15339,-1,-1,'sp_MSanonymous_status')
  7001. GO
  7002. CREATE PROCEDURE sp_MSanonymous_status
  7003. @agent_id           int,
  7004. @no_init_sync       int = 0,
  7005. @last_xact_seqno varbinary(16)
  7006. as
  7007.  
  7008.    set nocount on
  7009.  
  7010.    declare @virtual_agent_id int    /* virtual sub agent id */
  7011.    declare @anonymous_agent_id int  /* virtual anonymous agent id */
  7012.  
  7013.     -- Note @agent_id will be overwritten later.
  7014.     select  @virtual_agent_id =   virtual_agent_id,
  7015.             @anonymous_agent_id = anonymous_agent_id
  7016.         from MSdistribution_agents where
  7017.             id = @agent_id
  7018.     
  7019.     -- Return error if agent entry does not exists (being deleted).
  7020.     if @virtual_agent_id is null
  7021.     begin
  7022.         raiserror(21072, 16, -1)
  7023.         return(1)
  7024.     end
  7025.  
  7026.     -- If no init sync, use anonymous account to start immediately.
  7027.     -- If first time, or still working on the first snapshot, or just finished
  7028.     -- the first snapshot, use virtual account. This is to cover the case
  7029.     -- of multiple snapshot transactions (for example, one per article) in the first
  7030.     -- snapshot.
  7031.     -- otherwise use virtual anonymous account
  7032.     if  @no_init_sync = 1 
  7033.         select @agent_id = @anonymous_agent_id
  7034.     else if @last_xact_seqno = 0x00 or
  7035.         exists (select * from MSsubscriptions where
  7036.             agent_id = @virtual_agent_id and
  7037.             subscription_seqno = @last_xact_seqno)
  7038.         select @agent_id = @virtual_agent_id
  7039.     else
  7040.         select @agent_id = @anonymous_agent_id
  7041.     
  7042.     -- Call main procedure to get status
  7043.     exec dbo.sp_MSsubscription_status
  7044.         @agent_id = @agent_id
  7045. GO
  7046.  
  7047. raiserror(15339,-1,-1,'sp_MSadd_anonymous_agent')
  7048. GO
  7049. CREATE PROCEDURE sp_MSadd_anonymous_agent
  7050. @publisher_id       smallint,
  7051. @publisher_db       sysname,
  7052. @publication        sysname,
  7053. @subscriber_db      sysname,
  7054. @subscriber_name    sysname,
  7055. @anonymous_subid    uniqueidentifier output,
  7056. @agent_id           int output,
  7057. @reinitanon         bit = 0
  7058. as
  7059.  
  7060. /*
  7061. ** This stored procedure does not really add a job at distribution database;
  7062. ** if add a row in MSdistribution_agent table for anonymous subscription for the 
  7063. ** purpose of history logging
  7064. */
  7065.  
  7066.    set nocount on
  7067.    declare @distribution_type smallint
  7068.    declare @profile_id int
  7069.    declare @subscriber_id smallint
  7070.    declare @retcode int
  7071.    declare @publication_id int
  7072.    declare @virtual_agent_id int
  7073.    declare @anonymous_agent_id int
  7074.    declare @virtual smallint
  7075.    declare @virtual_anonymous smallint
  7076.    declare @new_agent_id int
  7077.    declare @anonymous int
  7078.    declare @publisher_database_id int
  7079.    declare @allow_anonymous bit
  7080.    declare @publication_type int
  7081.    declare @merge_publication_type int
  7082.    
  7083.    select @publication_type = NULL
  7084.    select @merge_publication_type = 2
  7085.    
  7086.    select @virtual = -1
  7087.    select @virtual_anonymous = -2
  7088.    select @anonymous = 2
  7089.    
  7090.     -- Check to see if the publication is valid and allow anonymous
  7091.     select @publication_id = publication_id, @allow_anonymous = allow_anonymous, @publication_type = publication_type
  7092.         from MSpublications where
  7093.         publisher_id = @publisher_id and
  7094.         publisher_db = @publisher_db and
  7095.         publication = @publication 
  7096.  
  7097.     if @publication_id is null
  7098.     begin
  7099.         RAISERROR (21040, 16, -1, @publication)
  7100.         return 1
  7101.     end
  7102.  
  7103.     if @publication_type = @merge_publication_type
  7104.     begin
  7105.         RAISERROR(21132, 16, -1, @publication)
  7106.         return 1
  7107.     end
  7108.  
  7109.     if @allow_anonymous = 0
  7110.     begin
  7111.         RAISERROR (21084, 16, -1, @publication)
  7112.         return 1       
  7113.     end
  7114.  
  7115.     if @subscriber_name is null
  7116.         select @subscriber_name = N''
  7117.  
  7118.     -- Get virtual ids
  7119.     select top 1 @virtual_agent_id = agent_id, 
  7120.         @publisher_database_id = publisher_database_id from MSsubscriptions where
  7121.         publisher_id = @publisher_id and
  7122.         publisher_db = @publisher_db and
  7123.         publication_id = @publication_id and
  7124.         subscriber_id = @virtual
  7125.  
  7126.     select top 1 @anonymous_agent_id = agent_id from MSsubscriptions where
  7127.         publisher_id = @publisher_id and
  7128.         publisher_db = @publisher_db and
  7129.         publication_id = @publication_id and
  7130.         subscriber_id = @virtual_anonymous
  7131.  
  7132.  
  7133.     -- Security check
  7134.     exec @retcode = dbo.sp_MScheck_pull_access
  7135.         @agent_id =  @anonymous_agent_id,
  7136.         @agent_type = 0 -- distribution agent   
  7137.     if @retcode <> 0 or @@error <> 0
  7138.         return (1)
  7139.  
  7140.     /*
  7141.     **  To return two more parameters for the purpose of anonymous monitoring
  7142.     ** 
  7143.     ** If @anonymous_subid is null, this is a new anonymous subscription; A new row would be inserted in MSdistribution_agents.
  7144.     ** And its id (identity) and newly generated ID will be returned; The new ID would be used in subscriber side.
  7145.     */
  7146.     select @subscriber_id = 0   -- for anonymous subscribers, ID is always 0
  7147.  
  7148.     select @agent_id = id from MSdistribution_agents 
  7149.         where anonymous_subid = @anonymous_subid
  7150.         
  7151.     
  7152.     IF @agent_id is null
  7153.         BEGIN
  7154.             if @anonymous_subid is not NULL and @anonymous_subid <> 0x00
  7155.                and @reinitanon = 0
  7156.             begin
  7157.                 -- Agent has be cleaned up, return error.
  7158.                 raiserror(21072, 16, -1)
  7159.                 return(1)
  7160.             end
  7161.             -- Generate a new subid only when the subscription is not 
  7162.             -- reinitialized 
  7163.             if @reinitanon = 0
  7164.             begin
  7165.                 select @anonymous_subid = newid()
  7166.             end
  7167.             SELECT @distribution_type = 3
  7168.  
  7169.             SELECT @profile_id = profile_id
  7170.             FROM msdb..MSagent_profiles
  7171.             WHERE agent_type = @distribution_type
  7172.                 AND def_profile = 1
  7173.  
  7174.             IF @profile_id IS NULL
  7175.             RETURN (1)
  7176.  
  7177.             INSERT into MSdistribution_agents (name, publisher_database_id, publisher_id, publisher_db, publication, 
  7178.                         subscriber_id, subscriber_db, subscription_type, local_job, job_id, subscription_guid, profile_id, anonymous_subid, 
  7179.                         subscriber_name, virtual_agent_id, anonymous_agent_id)
  7180.                         
  7181.                  VALUES (convert(nvarchar(40), @anonymous_subid), @publisher_database_id, @publisher_id, @publisher_db, @publication, 
  7182.                             @subscriber_id, @subscriber_db, @anonymous, 0, @anonymous_subid,
  7183.                             @anonymous_subid, @profile_id, @anonymous_subid, @subscriber_name,
  7184.                             @virtual_agent_id, @anonymous_agent_id)
  7185.             select @agent_id = @@identity
  7186.         END
  7187.         
  7188. GO
  7189.  
  7190.  
  7191. raiserror(15339,-1,-1,'sp_MSsubscription_status')
  7192. GO
  7193. CREATE PROCEDURE sp_MSsubscription_status
  7194. @agent_id int
  7195. as
  7196.  
  7197.     set nocount on
  7198.  
  7199.     declare @status tinyint
  7200.     declare @inactive tinyint
  7201.     declare @active tinyint
  7202.     declare @subscribed tinyint
  7203.     declare @article_id int
  7204.     declare @publisher_id int
  7205.     declare @publisher_db sysname
  7206.     declare @publication sysname
  7207.     declare @article sysname
  7208.     declare @msg nvarchar(255)
  7209.     declare @automatic tinyint
  7210.     declare @none tinyint
  7211.     declare @success int
  7212.     declare @retention int
  7213.     declare @last_sync datetime
  7214.  
  7215.     select @success = 2
  7216.     select @inactive = 0
  7217.     select @subscribed = 1
  7218.     select @active = 2
  7219.     SELECT @automatic = 1
  7220.     select @none = 2
  7221.  
  7222.     -- If one article is inactive, and no_sync subscription fail.
  7223.     if exists (select * from MSsubscriptions where
  7224.         status = @inactive and
  7225.         sync_type = @none and
  7226.         agent_id = @agent_id)
  7227.     begin
  7228.         -- The subscription was deactivated.
  7229.         raiserror(21074, 16,-1)
  7230.         return(1)
  7231.     end
  7232.  
  7233.     -- If one article is inactive, fail.
  7234.     if exists (select * from MSsubscriptions where
  7235.         status = @inactive and
  7236.         sync_type = @automatic and
  7237.         agent_id = @agent_id)
  7238.     begin
  7239.         -- The subscription was deactivated.
  7240.         raiserror(21074, 16,-1)
  7241.         return(1)
  7242.     end
  7243.  
  7244.     select top 1 @article_id = article_id,
  7245.         @publisher_id = publisher_id,
  7246.         @publisher_db = publisher_db
  7247.         from MSsubscriptions where
  7248.         agent_id = @agent_id and
  7249.         sync_type = @automatic and
  7250.         status = @subscribed
  7251.  
  7252.     if @article_id is not null
  7253.     begin
  7254.         -- Get the publication name to use later in the formated message
  7255.         select @publication = publication from MSpublications where
  7256.             publisher_id = @publisher_id and
  7257.             publisher_db = @publisher_db and
  7258.             publication_id = (select publication_id from MSsubscriptions where
  7259.                 publisher_id = @publisher_id and
  7260.                 publisher_db = @publisher_db and
  7261.                 article_id = @article_id and
  7262.                 agent_id = @agent_id)
  7263.  
  7264.         -- If there's more than one article in subscribed state
  7265.         -- Send a general waiting message.
  7266.         -- Otherwise, indicate the article name
  7267.         if exists (select * from MSsubscriptions where
  7268.             agent_id = @agent_id and
  7269.             status = @subscribed and
  7270.             sync_type = @automatic and
  7271.             article_id <> @article_id)
  7272.         begin
  7273.             -- Snapshot not available message
  7274.             if @publication is not null
  7275.                 select @msg = formatmessage(21075, @publication)
  7276.             else -- It is null for 6.5
  7277.                 select @msg = formatmessage(21088)
  7278.         end
  7279.         else
  7280.         begin
  7281.             -- article_id is unique across pub db
  7282.             select @article = article from MSarticles where
  7283.                 article_id = @article_id and
  7284.                 publisher_id = @publisher_id and
  7285.                 publisher_db = @publisher_db
  7286.             -- It is null for 6.5
  7287.             if @article is not null
  7288.                 select @msg = formatmessage(21076, @article)
  7289.             else
  7290.             begin
  7291.                 -- Snapshot not available message
  7292.                 if @publication is not null
  7293.                     select @msg = formatmessage(21075, @publication)
  7294.                 else -- It is null for 6.5
  7295.                     select @msg = formatmessage(21088)
  7296.             end
  7297.         end
  7298.  
  7299.         -- If one article is active, the status is active
  7300.         if exists ( select * from MSsubscriptions where
  7301.             agent_id = @agent_id and
  7302.             sync_type = @automatic and
  7303.             status = @active)
  7304.             set @status = @active
  7305.         else
  7306.             set @status = @subscribed
  7307.     end
  7308.  
  7309.  
  7310.     -- If nothing returned, all articles are active.
  7311.     select 'msg' = @msg, 'status' = @status 
  7312.         where @msg is not null
  7313.  
  7314. GO
  7315.  
  7316.  
  7317.  
  7318.  
  7319. raiserror(15339,-1,-1,'sp_MSget_last_transaction')
  7320. GO
  7321. CREATE PROCEDURE sp_MSget_last_transaction
  7322. @publisher_id int,
  7323. @publisher_db sysname
  7324.  
  7325. AS
  7326.    declare @max_xact_seqno nvarchar(16)
  7327.    declare @publisher_database_id int
  7328.  
  7329.    set nocount on 
  7330.     
  7331.     -- Get publisher database id.
  7332.     SELECT @publisher_database_id = id from MSpublisher_databases where publisher_id = @publisher_id and 
  7333.         publisher_db = @publisher_db
  7334.     
  7335.    set rowcount 1
  7336.    select rt.xact_id, rt.xact_seqno
  7337.       from
  7338.       MSrepl_transactions rt
  7339.       where 
  7340.          rt.publisher_database_id = @publisher_database_id and
  7341.          not xact_id = 0x0
  7342.          order by xact_seqno desc
  7343.    set rowcount 0
  7344. GO
  7345.  
  7346. raiserror(15339,-1,-1,'sp_MSadd_subscriber_info')
  7347. GO
  7348. CREATE PROCEDURE sp_MSadd_subscriber_info
  7349. @publisher sysname,
  7350. @subscriber sysname,
  7351. @type tinyint = 0,
  7352. @login sysname = 'sa',
  7353. @password sysname = NULL,
  7354. @commit_batch_size int = 100,
  7355. @status_batch_size int = 100,
  7356. @flush_frequency int = 0,
  7357. @frequency_type int = 4,
  7358. @frequency_interval int = 1,
  7359. @frequency_relative_interval int = 1,
  7360. @frequency_recurrence_factor int = 0,
  7361. @frequency_subday int = 4,
  7362. @frequency_subday_interval int = 5,
  7363. @active_start_time_of_day int = 0,
  7364. @active_end_time_of_day int = 235959,
  7365. @active_start_date int = 0,
  7366. @active_end_date int = 99991231,
  7367. @retryattempts int = 0,    
  7368. @retrydelay int = 0,
  7369. @description nvarchar (255) = NULL,
  7370. @security_mode int = 1, /* 0 standard; 1 integrated */
  7371. @encrypted_password bit = 0
  7372.  
  7373. AS
  7374.    set nocount on
  7375.  
  7376.    declare @retcode int
  7377.    declare @oledbprovider nvarchar(256)
  7378.    declare @platform_nt binary
  7379.  
  7380.    select @platform_nt = 0x1
  7381.  
  7382.     IF (UPPER(@subscriber) = UPPER(@@SERVERNAME) and ( @platform_nt != platform() & @platform_nt ) and @security_mode = 1)
  7383.         BEGIN
  7384.             RAISERROR(21038, 16, -1)
  7385.             RETURN (1)
  7386.         END
  7387.  
  7388. /* Add the subscriber to sysservers as a RPC server, if it does not
  7389.    ** already exist.
  7390.    */
  7391.    if not exists (select * from  master..sysservers where  UPPER(srvname) = UPPER(@subscriber))
  7392.       begin
  7393.           exec @retcode = dbo.sp_addserver @subscriber
  7394.           if @retcode <> 0
  7395.              return 1
  7396.       end
  7397.    
  7398.     -- Encrypt the password
  7399.     IF @encrypted_password = 0
  7400.     BEGIN
  7401.         EXEC @retcode = master.dbo.xp_repl_encrypt @password OUTPUT
  7402.         IF @@error <> 0 OR @retcode <> 0
  7403.             return 1
  7404.     END
  7405.  
  7406.     if (@type = 3)
  7407.     begin
  7408.         select @oledbprovider = providername from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  7409.         if (@oledbprovider = 'sqloledb')
  7410.             select @security_mode = 1
  7411.         else
  7412.             select @security_mode = 0
  7413.     end
  7414.  
  7415.    /* Delete any existing row */
  7416.    delete from MSsubscriber_info where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  7417.    if @@error <> 0
  7418.      return 1
  7419.    delete from MSsubscriber_schedule where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  7420.    if @@error <> 0
  7421.      return 1
  7422.  
  7423.    begin tran
  7424.    save TRAN addsub_info
  7425.  
  7426.    insert MSsubscriber_info (publisher, subscriber, type, login, password, description, security_mode)
  7427.          values (@publisher, @subscriber, @type, @login, @password, @description, @security_mode)
  7428.     if @@error <> 0
  7429.     goto UNDO
  7430.  
  7431.     /*
  7432.     ** Schedule information is added for backward compartibility reason, agent_type = 0
  7433.     */
  7434.    insert MSsubscriber_schedule values(@publisher, @subscriber, 0, @frequency_type,
  7435.                                         @frequency_interval,
  7436.                                         @frequency_relative_interval,
  7437.                                         @frequency_recurrence_factor ,
  7438.                                         @frequency_subday ,
  7439.                                         @frequency_subday_interval,
  7440.                                         @active_start_time_of_day,
  7441.                                         @active_end_time_of_day ,
  7442.                                         @active_start_date ,
  7443.                                         @active_end_date )
  7444.     if @@error <> 0
  7445.     goto UNDO
  7446.     COMMIT TRAN
  7447.  
  7448.     Return (0)
  7449. UNDO:
  7450.     if @@TRANCOUNT > 0
  7451.     begin
  7452.         ROLLBACK TRAN addsub_info
  7453.         COMMIT TRAN
  7454.     end
  7455.     return (1)
  7456. GO
  7457.  
  7458. raiserror(15339,-1,-1,'sp_MSadd_subscriber_schedule')
  7459. GO
  7460. CREATE PROCEDURE sp_MSadd_subscriber_schedule
  7461. @publisher sysname,
  7462. @subscriber sysname,
  7463. @agent_type smallint = 0,   -- 0 for distribution agent, 1 for merge agent
  7464. @frequency_type int = 4,
  7465. @frequency_interval int = 1,
  7466. @frequency_relative_interval int = 1,
  7467. @frequency_recurrence_factor int = 0,
  7468. @frequency_subday int = 4,
  7469. @frequency_subday_interval int = 5,
  7470. @active_start_time_of_day int = 0,
  7471. @active_end_time_of_day int = 235959,
  7472. @active_start_date int = 0,
  7473. @active_end_date int = 99991231
  7474.  
  7475. AS
  7476.    set nocount on
  7477.  
  7478.    declare @retcode int
  7479.  
  7480.    /* Add the subscriber to sysservers as a RPC server, if it does not
  7481.    ** already exist.
  7482.    */
  7483.    if not exists (select * from  master..sysservers where  UPPER(srvname) = UPPER(@subscriber))
  7484.       begin
  7485.           exec @retcode = dbo.sp_addserver @subscriber
  7486.           if @retcode <> 0
  7487.              return 1
  7488.       end
  7489.  
  7490.    /* Delete any existing row */
  7491.    if exists (select * from MSsubscriber_schedule where
  7492.        UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type=@agent_type)
  7493.        begin
  7494.            delete from MSsubscriber_schedule 
  7495.            where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type=@agent_type
  7496.           if @@error <> 0
  7497.              return 1
  7498.        end
  7499.  
  7500.    insert MSsubscriber_schedule (publisher, subscriber, agent_type, 
  7501.       frequency_type, frequency_interval, frequency_relative_interval,
  7502.       frequency_recurrence_factor, frequency_subday, frequency_subday_interval,
  7503.       active_start_time_of_day, active_end_time_of_day, active_start_date,
  7504.       active_end_date)
  7505.       
  7506.       values (@publisher, @subscriber, @agent_type, 
  7507.       @frequency_type, @frequency_interval, @frequency_relative_interval,
  7508.       @frequency_recurrence_factor, @frequency_subday, @frequency_subday_interval,
  7509.       @active_start_time_of_day, @active_end_time_of_day, @active_start_date,
  7510.       @active_end_date)
  7511.    if @@error <> 0
  7512.       return 1
  7513. GO
  7514.  
  7515.  
  7516.  
  7517. raiserror(15339,-1,-1,'sp_MSupdate_subscriber_info')
  7518. GO
  7519. CREATE PROCEDURE sp_MSupdate_subscriber_info
  7520. @publisher sysname,
  7521. @subscriber sysname,
  7522. @type tinyint = NULL,
  7523. @login sysname = NULL,
  7524. @password sysname = '%',
  7525. @commit_batch_size int = NULL,
  7526. @status_batch_size int = NULL,
  7527. @flush_frequency int = NULL,
  7528. @frequency_type int = NULL,
  7529. @frequency_interval int = NULL,
  7530. @frequency_relative_interval int = NULL,
  7531. @frequency_recurrence_factor int = NULL,
  7532. @frequency_subday int = NULL,
  7533. @frequency_subday_interval int = NULL,
  7534. @active_start_time_of_day int = NULL,
  7535. @active_end_time_of_day int = NULL,
  7536. @active_start_date int = NULL,
  7537. @active_end_date int = NULL,
  7538. @retryattempts int = NULL,
  7539. @retrydelay int = NULL,
  7540. @description nvarchar (255) = NULL,
  7541. @security_mode int = NULL
  7542.  
  7543. AS
  7544.    set nocount on
  7545.    
  7546.    declare @cmd1 nvarchar (255)
  7547.    declare @retcode int
  7548.    declare @platform_nt binary
  7549.  
  7550.    select @platform_nt = 0x1
  7551.  
  7552.    IF (UPPER(@subscriber) = UPPER(@@SERVERNAME) and ( @platform_nt != platform() & @platform_nt ) and @security_mode = 1)
  7553.         BEGIN
  7554.             RAISERROR(21038, 16, -1)
  7555.             RETURN (1)
  7556.         END
  7557.  
  7558.  
  7559.    begin transaction
  7560.    save transaction update_subscriber
  7561.    
  7562.    /* Check if subscriber exists */
  7563.    if not exists (select * from MSsubscriber_info 
  7564.                   where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber))
  7565.        goto FAILED
  7566.  
  7567.    if not exists (select * from MSsubscriber_schedule 
  7568.                   where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0)
  7569.        goto FAILED    
  7570.    
  7571.    if @type is not NULL
  7572.       update MSsubscriber_info set type = @type 
  7573.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  7574.       if @@error <> 0
  7575.          goto FAILED
  7576.    
  7577.    if @security_mode is not NULL
  7578.       update MSsubscriber_info set security_mode = @security_mode 
  7579.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  7580.       if @@error <> 0
  7581.          goto FAILED
  7582.   
  7583.    if @login is not NULL
  7584.       update MSsubscriber_info set login = @login 
  7585.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  7586.       if @@error <> 0
  7587.          goto FAILED
  7588.    
  7589.    if @password <> '%'
  7590.    begin
  7591.         -- Encrypt the password
  7592.         EXEC @retcode = master.dbo.xp_repl_encrypt @password OUTPUT
  7593.         IF @@error <> 0 OR @retcode <> 0
  7594.             goto FAILED
  7595.         update MSsubscriber_info set password = @password 
  7596.             where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  7597.         if @@error <> 0
  7598.             goto FAILED
  7599.    end
  7600.  
  7601.    
  7602.    if @frequency_type is not NULL
  7603.       update MSsubscriber_schedule set frequency_type = @frequency_type 
  7604.         where  UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0
  7605.       if @@error <> 0
  7606.          goto FAILED
  7607.    
  7608.    if @frequency_interval is not NULL
  7609.       update MSsubscriber_schedule set frequency_interval = @frequency_interval 
  7610.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0
  7611.       if @@error <> 0
  7612.          goto FAILED
  7613.    
  7614.    if @frequency_relative_interval is not NULL
  7615.       update MSsubscriber_schedule set frequency_relative_interval = @frequency_relative_interval 
  7616.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0
  7617.        if @@error <> 0
  7618.          goto FAILED
  7619.    
  7620.    if @frequency_recurrence_factor is not NULL
  7621.       update MSsubscriber_schedule set frequency_recurrence_factor = @frequency_recurrence_factor 
  7622.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0
  7623.       if @@error <> 0
  7624.          goto FAILED
  7625.    
  7626.    if @frequency_subday is not NULL
  7627.       update MSsubscriber_schedule set frequency_subday = @frequency_subday 
  7628.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0
  7629.       if @@error <> 0
  7630.          goto FAILED
  7631.    
  7632.    if @frequency_subday_interval is not NULL
  7633.       update MSsubscriber_schedule set frequency_subday_interval = @frequency_subday_interval 
  7634.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0
  7635.       if @@error <> 0
  7636.          goto FAILED
  7637.    
  7638.    if @active_start_time_of_day is not NULL
  7639.       update MSsubscriber_schedule set active_start_time_of_day = @active_start_time_of_day 
  7640.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0
  7641.       if @@error <> 0
  7642.          goto FAILED
  7643.    
  7644.    if @active_end_time_of_day is not NULL
  7645.       update MSsubscriber_schedule set active_end_time_of_day = @active_end_time_of_day 
  7646.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0
  7647.       if @@error <> 0
  7648.          goto FAILED
  7649.    
  7650.    if @active_start_date is not NULL
  7651.       update MSsubscriber_schedule set active_start_date = @active_start_date 
  7652.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0
  7653.       if @@error <> 0
  7654.          goto FAILED
  7655.    
  7656.    if @active_end_date is not NULL
  7657.       update MSsubscriber_schedule set active_end_date = @active_end_date 
  7658.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0
  7659.       if @@error <> 0
  7660.          goto FAILED
  7661.    
  7662.    if @description is not NULL
  7663.       update MSsubscriber_info set description = @description 
  7664.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  7665.       if @@error <> 0
  7666.          goto FAILED
  7667.  
  7668.     if @security_mode is not NULL
  7669.       update MSsubscriber_info set security_mode = @security_mode 
  7670.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  7671.       if @@error <> 0
  7672.          goto FAILED
  7673.  
  7674.    commit transaction
  7675.    return (0)
  7676.    
  7677. FAILED:
  7678.     if @@trancount > 0
  7679.     begin
  7680.         rollback transaction update_subscriber
  7681.         commit tran -- to finish off the tran we started in this proc (though 
  7682.                     -- work was rolled back to savepoint)
  7683.     end
  7684.    return (1)
  7685. GO
  7686.  
  7687. raiserror(15339,-1,-1,'sp_MScheck_Jet_Subscriber')
  7688. GO
  7689. CREATE PROCEDURE sp_MScheck_Jet_Subscriber
  7690. @subscriber                sysname,
  7691. @is_jet                    int OUTPUT,
  7692. @Jet_datasource_path    sysname OUTPUT
  7693. AS
  7694.  
  7695. select @is_jet = 0
  7696. IF EXISTS (select * from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  7697.                 and upper(providername) = 'MICROSOFT.JET.OLEDB.4.0')
  7698. begin
  7699.     select @is_jet = 1
  7700.     select @Jet_datasource_path = datasource from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  7701. end
  7702. return (0)
  7703. GO
  7704.  
  7705. /*
  7706. ** this procedure is to check if merge agent is has expired based on retention
  7707. ** period. Note that if it does, a reinitialization would make it work.
  7708. */
  7709. raiserror(15339,-1,-1,'sp_MScheckretention')
  7710. GO
  7711. CREATE PROCEDURE sp_MScheckretention
  7712. @agent_id                int,
  7713. @schemachangever        int
  7714. AS
  7715. declare     @publisher_id            int
  7716. declare     @publisher_db        sysname
  7717. declare     @publication        sysname
  7718. declare        @expired            int
  7719. declare        @min_valid_day        datetime
  7720. declare        @retention            int
  7721. declare     @success            int
  7722.  
  7723. select @expired  = 0
  7724. select @success = 2
  7725.  
  7726. select @publisher_id=publisher_id, @publisher_db=publisher_db, @publication=publication 
  7727. from MSmerge_agents 
  7728. where id = @agent_id
  7729.  
  7730. select @retention = retention 
  7731. from MSpublications 
  7732. where publisher_id=@publisher_id and publisher_db=@publisher_db and publication=@publication 
  7733.  
  7734. if @retention is not NULL and @retention > 0
  7735. begin
  7736.     select @min_valid_day = dateadd(day, @retention * (-1), getdate()) 
  7737.     if exists (select * from MSmerge_history where agent_id=@agent_id) 
  7738.             and not exists (select * from MSmerge_history where agent_id=@agent_id and time > @min_valid_day)
  7739.             and @schemachangever >0
  7740.         select @expired = 1
  7741. end
  7742. select @expired 
  7743. GO
  7744.  
  7745. raiserror(15339,-1,-1,'sp_MSupdate_subscriber_schedule')
  7746. GO
  7747. CREATE PROCEDURE sp_MSupdate_subscriber_schedule
  7748. @publisher sysname,
  7749. @subscriber sysname,
  7750. @agent_type tinyint = NULL,
  7751. @frequency_type int = NULL,
  7752. @frequency_interval int = NULL,
  7753. @frequency_relative_interval int = NULL,
  7754. @frequency_recurrence_factor int = NULL,
  7755. @frequency_subday int = NULL,
  7756. @frequency_subday_interval int = NULL,
  7757. @active_start_time_of_day int = NULL,
  7758. @active_end_time_of_day int = NULL,
  7759. @active_start_date int = NULL,
  7760. @active_end_date int = NULL
  7761.  
  7762. AS
  7763.    set nocount on
  7764.    
  7765.    declare @cmd1 nvarchar (255)
  7766.    declare @retcode int
  7767.    
  7768.  
  7769.    begin transaction
  7770.    save transaction update_subscriber_schedule
  7771.    
  7772.    /* Check if subscriber exists */
  7773.    if not exists (select * from MSsubscriber_info 
  7774.             where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber))
  7775.        goto FAILED
  7776.        
  7777.     if not exists (select * from MSsubscriber_schedule 
  7778.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type)
  7779.        goto FAILED
  7780.     
  7781.    
  7782.    if @frequency_type is not NULL
  7783.       update MSsubscriber_schedule set frequency_type = @frequency_type 
  7784.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type
  7785.       if @@error <> 0
  7786.          goto FAILED
  7787.    
  7788.    if @frequency_interval is not NULL
  7789.       update MSsubscriber_schedule set frequency_interval = @frequency_interval 
  7790.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type
  7791.       if @@error <> 0
  7792.          goto FAILED
  7793.    
  7794.    if @frequency_relative_interval is not NULL
  7795.       update MSsubscriber_schedule set frequency_relative_interval = @frequency_relative_interval 
  7796.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type
  7797.       if @@error <> 0
  7798.          goto FAILED
  7799.    
  7800.    if @frequency_recurrence_factor is not NULL
  7801.       update MSsubscriber_schedule set frequency_recurrence_factor = @frequency_recurrence_factor 
  7802.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type
  7803.        if @@error <> 0
  7804.          goto FAILED
  7805.    
  7806.    if @frequency_subday is not NULL
  7807.       update MSsubscriber_schedule set frequency_subday = @frequency_subday 
  7808.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type
  7809.       if @@error <> 0
  7810.          goto FAILED
  7811.    
  7812.    if @frequency_subday_interval is not NULL
  7813.       update MSsubscriber_schedule set frequency_subday_interval = @frequency_subday_interval 
  7814.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type
  7815.       if @@error <> 0
  7816.          goto FAILED
  7817.    
  7818.    if @active_start_time_of_day is not NULL
  7819.       update MSsubscriber_schedule set active_start_time_of_day = @active_start_time_of_day 
  7820.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type
  7821.       if @@error <> 0
  7822.          goto FAILED
  7823.    
  7824.    if @active_end_time_of_day is not NULL
  7825.       update MSsubscriber_schedule set active_end_time_of_day = @active_end_time_of_day 
  7826.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type
  7827.       if @@error <> 0
  7828.          goto FAILED
  7829.    
  7830.    if @active_start_date is not NULL
  7831.       update MSsubscriber_schedule set active_start_date = @active_start_date 
  7832.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type
  7833.       if @@error <> 0
  7834.          goto FAILED
  7835.    
  7836.    if @active_end_date is not NULL
  7837.       update MSsubscriber_schedule set active_end_date = @active_end_date 
  7838.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type
  7839.       if @@error <> 0
  7840.          goto FAILED
  7841.  
  7842.    commit transaction
  7843.    return (0)
  7844.    
  7845. FAILED:
  7846.     if @@trancount > 0
  7847.     begin
  7848.         rollback transaction update_subscriber_schedule
  7849.         commit transaction      -- to finish off the tran we started in this proc (though 
  7850.                                 -- work was rolled back to savepoint)
  7851.     end
  7852.    return (1)
  7853. GO
  7854.  
  7855.  
  7856. raiserror(15339,-1,-1,'sp_MSdrop_subscriber_info')
  7857. GO
  7858. CREATE PROCEDURE sp_MSdrop_subscriber_info
  7859. @publisher sysname,
  7860. @subscriber sysname
  7861.  
  7862. AS
  7863.     set nocount on
  7864.  
  7865.     declare @srvid smallint
  7866.     declare @publisher_id smallint
  7867.     declare @publisher_db sysname
  7868.   
  7869.     if exists (select * from MSsubscriber_info where
  7870.         UPPER(subscriber) = UPPER(@subscriber))
  7871.     begin
  7872.  
  7873.         select @srvid = srvid from master..sysservers where lower(srvname) = lower(@subscriber)
  7874.  
  7875.         -- For SQL server publishers, drop the existing subscriptions.
  7876.         -- This has to be done for 65 upgrade.
  7877.         -- For third party, check for error.
  7878.         if exists (select * from msdb..MSdistpublishers where 
  7879.             lower(name) = lower(@publisher) and
  7880.             thirdparty_flag = 0)
  7881.         begin
  7882.             -- This is needed for 6.5 upgrade.
  7883.             -- Remove subscription entries for this publisher and subscriber pair
  7884.             -- Get dist publisher ID
  7885.             exec dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  7886.             delete MSsubscriptions where subscriber_id = @srvid and 
  7887.                 publisher_id = @publisher_id
  7888.         end
  7889.         else
  7890.         begin
  7891.             if exists (select * from MSsubscriptions where subscriber_id = @srvid)
  7892.             begin
  7893.                 raiserror(20100, 16, -1, @subscriber)
  7894.                 return (1)
  7895.             end
  7896.         end
  7897.  
  7898.         delete MSsubscriber_info where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  7899.         if @@error <> 0
  7900.             return 1
  7901.         delete MSsubscriber_schedule where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  7902.         if @@error <> 0
  7903.             return 1    
  7904.     end
  7905. GO
  7906.  
  7907. -- delete the agent rows that are orphaned for some external reasons, e.g., publishing database dropped,
  7908. -- the agent entry for anonymous TRAN/MERGE subscriptions. 
  7909. -- Can be called directly by user to explicitly cleanup metadata in distribution database
  7910.  
  7911. raiserror(15339,-1,-1,'sp_MScleanup_agent_entry')
  7912. GO
  7913. CREATE PROCEDURE sp_MScleanup_agent_entry
  7914. AS
  7915.     
  7916.     declare @min_valid_day         datetime
  7917.  
  7918.     declare @publisher_id         int
  7919.     declare @subscriber_id         int
  7920.     declare @publication         sysname
  7921.     declare @publisher_db         sysname
  7922.     declare @subscriber_db         sysname
  7923.     declare @retention             int
  7924.     declare @publication_type     int
  7925.     declare @agent_id            int
  7926.         , @retcode int
  7927.  
  7928.     set nocount on
  7929.  
  7930.     declare PC CURSOR LOCAL FAST_FORWARD for 
  7931.         select distinct publisher_id, publisher_db, publication, retention, publication_type from MSpublications
  7932.             where retention<>0
  7933.     open PC
  7934.     fetch PC into @publisher_id, @publisher_db, @publication, @retention, @publication_type
  7935.     while (@@fetch_status <> -1)
  7936.     begin    
  7937.         if @publication_type = 2  --merge publication
  7938.         begin
  7939.             select @min_valid_day = dateadd(day, @retention * (-2), getdate()) 
  7940.  
  7941.             declare hC CURSOR LOCAL FAST_FORWARD FOR 
  7942.                 select id from MSmerge_agents where creation_date < @min_valid_day
  7943.                     and not exists (select * from MSmerge_history where agent_id = id and time > @min_valid_day)
  7944.                     and publisher_id=@publisher_id
  7945.                     and publisher_db = @publisher_db
  7946.                     and publication = @publication   
  7947.                     -- Only do this for anonymous agents
  7948.                     and subscriber_name is not null         
  7949.             for read only
  7950.             open hC
  7951.             fetch hC into @agent_id
  7952.             while (@@fetch_status <> -1)
  7953.             begin
  7954.                 exec @retcode = dbo.sp_MSdrop_merge_agentid @agent_id
  7955.                 if @retcode <> 0 or @@error <> 0
  7956.                     return (1)
  7957.                 fetch hC into @agent_id
  7958.             end
  7959.             close hC
  7960.             deallocate hC
  7961.         end
  7962.            else if @publication_type in (0,1) --Tran level publication
  7963.               begin  
  7964.                 select @min_valid_day = dateadd(hour, @retention * (-1), getdate())    
  7965.                 -- Only do this for anonymous agents
  7966.                 declare hC CURSOR LOCAL FAST_FORWARD FOR 
  7967.                     select id from MSdistribution_agents where creation_date < @min_valid_day
  7968.                         and not exists (select * from MSdistribution_history where agent_id = id and time > @min_valid_day)
  7969.                         and publisher_id=@publisher_id
  7970.                         and publisher_db = @publisher_db
  7971.                         and publication = @publication            
  7972.                         -- Only do this for anonymous agents
  7973.                         and subscriber_name is not null                             
  7974.                 for read only
  7975.                 open hC
  7976.                 fetch hC into @agent_id
  7977.                 while (@@fetch_status <> -1)
  7978.                 begin
  7979.                     exec @retcode = dbo.sp_MSdrop_distribution_agentid @agent_id
  7980.                     if @retcode <> 0 or @@error <> 0
  7981.                         return (1)
  7982.                     fetch hC into @agent_id
  7983.                 end
  7984.             close hC
  7985.             deallocate hC
  7986.             end
  7987.           fetch PC into @publisher_id, @publisher_db, @publication, @retention, @publication_type
  7988.     end
  7989.     close PC
  7990.     deallocate PC
  7991.        return (0)
  7992. FAILURE:
  7993.     close PC
  7994.     deallocate PC
  7995.        return (1)        
  7996. GO
  7997. raiserror(15339,-1,-1,'sp_MShelp_subscription_status')
  7998. GO
  7999. CREATE PROCEDURE sp_MShelp_subscription_status(
  8000. @publisher          sysname,
  8001. @publisher_db       sysname,
  8002. @publication        sysname,
  8003. @subscriber         sysname,
  8004. @subscriber_db      sysname,
  8005. @retention          int,
  8006. @out_of_date        int OUTPUT,
  8007. @independent_agent  bit = 0
  8008. )AS
  8009.  
  8010. declare @subscriber_id          int
  8011. declare @publisher_id           int
  8012. declare @publication_id         int
  8013. declare @retcode                int
  8014. declare @agent_id               int
  8015. declare @min_valid_day          datetime
  8016. declare @subscription_time      datetime
  8017. declare @last_history            datetime
  8018. declare @last_status            int
  8019.  
  8020. select @out_of_date = 0 -- Default value set to in-sync
  8021. select @publisher_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)
  8022. select @subscriber_id = srvid from master..sysservers where UPPER(srvname)=UPPER(@subscriber)
  8023.  
  8024. select  @publication_id = publication_id
  8025.         from MSpublications where
  8026.         publisher_id = @publisher_id and
  8027.         publisher_db = @publisher_db and
  8028.         publication = @publication
  8029.  
  8030. select @subscription_time = subscription_time
  8031.         from MSsubscriptions where
  8032.             publisher_id = @publisher_id and
  8033.             publisher_db = @publisher_db and
  8034.             publication_id = @publication_id and
  8035.             subscriber_id = @subscriber_id and
  8036.             subscriber_db = @subscriber_db
  8037.             
  8038. select @min_valid_day = dateadd(hour, -@retention, getdate())
  8039.         
  8040. BEGIN TRAN
  8041.     select @agent_id = id from MSdistribution_agents 
  8042.         where   publisher_id = @publisher_id and 
  8043.                 publisher_db = @publisher_db and 
  8044.                 ((publication = @publication and @independent_agent = 1 ) 
  8045.                     or (LOWER(publication) = 'all' and @independent_agent = 0)) and
  8046.                 subscriber_id = @subscriber_id and  
  8047.                 subscriber_db = @subscriber_db
  8048.  
  8049.     if @agent_id is NOT NULL
  8050.         begin
  8051.             select Top 1 @last_status = runstatus, @last_history = time 
  8052.                 from MSdistribution_history where agent_id = @agent_id
  8053.                     order by timestamp DESC
  8054.                     
  8055.             -- if failure then get the last success; if any; else use the existing value                    
  8056.             
  8057.             if @last_status = 6 and EXISTS (select * from MSdistribution_history where agent_id = @agent_id and runstatus = 2) 
  8058.                 select Top 1 @last_history = time 
  8059.                     from MSdistribution_history where agent_id = @agent_id and runstatus = 2
  8060.                         order by timestamp DESC    
  8061.             
  8062.             if EXISTS (select * from MSdistribution_history where agent_id = @agent_id) and (@last_history < @min_valid_day) 
  8063.                 and (@retention <> 0)
  8064.                 select @out_of_date = 1
  8065.             else 
  8066.                 if (not EXISTS (select * from MSdistribution_history where agent_id = @agent_id)) and
  8067.                         (@subscription_time < @min_valid_day) and (@retention <> 0)
  8068.                 select @out_of_date = 1
  8069.         end
  8070.         
  8071. COMMIT TRAN
  8072. return (0)
  8073.  
  8074. FAILURE:
  8075.     if @@TRANCOUNT = 1
  8076.         ROLLBACK TRAN
  8077.     else
  8078.         COMMIT TRAN
  8079.     return (1)
  8080. GO
  8081.  
  8082.  
  8083.  
  8084. raiserror(15339,-1,-1,'sp_MShelp_subscriber_info')
  8085. GO
  8086. CREATE PROCEDURE sp_MShelp_subscriber_info
  8087. @publisher sysname = '%',
  8088. @subscriber sysname = '%',
  8089. @found int = NULL    OUTPUT,
  8090. @show_password bit = 1
  8091.  
  8092. AS
  8093.    set nocount on
  8094.    
  8095.    DECLARE @no_rows bit
  8096.  
  8097.     /*
  8098.     ** Initializations.
  8099.     */
  8100.     IF @found is NULL
  8101.     BEGIN
  8102.         SELECT @no_rows=0
  8103.     END
  8104.     ELSE
  8105.     BEGIN
  8106.         SELECT @no_rows=1
  8107.     END
  8108.  
  8109.    if exists (select * from MSsubscriber_info 
  8110.                where (@publisher = '%' or UPPER(publisher) = UPPER(@publisher)) 
  8111.                  and (@subscriber = '%' or UPPER(subscriber) = UPPER(@subscriber)))
  8112.    begin
  8113.         select @found = 1
  8114.         if @no_rows <>0 return(0)
  8115.    end
  8116.    else
  8117.    begin
  8118.         select @found = 0
  8119.         if @no_rows <>0 return(0)
  8120.    end
  8121.  
  8122.    if exists (select * from MSsubscriber_schedule 
  8123.                where (@publisher = N'%' or UPPER(publisher) = UPPER(@publisher))
  8124.                  and (@subscriber = N'%' or UPPER(subscriber) = UPPER(@subscriber)))
  8125.     begin
  8126.     
  8127.      select Sinfo.publisher,
  8128.             Sinfo.subscriber,
  8129.             Sinfo.type,
  8130.             Sinfo.login,
  8131.             case when @show_password = 1 then Sinfo.password
  8132.             else convert(sysname, NULL) end,
  8133.             100,  -- commit_batch_size, no longer supported
  8134.             100,  -- status_batch_size, no longer supported
  8135.             1,    -- flush_frequency, no longer supported
  8136.             sch1.frequency_type, 
  8137.             sch1.frequency_interval,
  8138.             sch1.frequency_relative_interval,
  8139.             sch1.frequency_recurrence_factor,
  8140.             sch1.frequency_subday,
  8141.             sch1.frequency_subday_interval,
  8142.             sch1.active_start_time_of_day,
  8143.             sch1.active_end_time_of_day,
  8144.             sch1.active_start_date,
  8145.             sch1.active_end_date,
  8146.             4, -- retryattempt, no longer exist
  8147.             4,  -- retrydelay, no longer exist
  8148.             Sinfo.description,
  8149.             Sinfo.security_mode,
  8150.             sch2.frequency_type, 
  8151.             sch2.frequency_interval,
  8152.             sch2.frequency_relative_interval,
  8153.             sch2.frequency_recurrence_factor,
  8154.             sch2.frequency_subday,
  8155.             sch2.frequency_subday_interval,
  8156.             sch2.active_start_time_of_day,
  8157.             sch2.active_end_time_of_day,
  8158.             sch2.active_start_date,
  8159.             sch2.active_end_date
  8160.             
  8161.     from (MSsubscriber_info as Sinfo LEFT OUTER JOIN MSsubscriber_schedule as sch1 
  8162.         on UPPER(Sinfo.publisher)=UPPER(sch1.publisher) AND UPPER(Sinfo.subscriber)=UPPER(sch1.subscriber) and sch1.agent_type=0)
  8163.         LEFT OUTER JOIN MSsubscriber_schedule as sch2
  8164.             on UPPER(Sinfo.publisher)=UPPER(sch2.publisher) AND UPPER(Sinfo.subscriber)=UPPER(sch2.subscriber) 
  8165.                     and sch2.agent_type=1
  8166.     where (@publisher = N'%' or UPPER(Sinfo.publisher) = UPPER(@publisher)) and 
  8167.           (@subscriber = N'%' or UPPER(Sinfo.subscriber) = UPPER(@subscriber))                 
  8168.     
  8169.     end
  8170. GO
  8171.  
  8172. raiserror(15339,-1,-1,'sp_MSdistribution_counters')
  8173. go
  8174. CREATE PROCEDURE sp_MSdistribution_counters
  8175. @publisher sysname      /* publication server name */
  8176. AS
  8177.  
  8178.     set nocount on
  8179.  
  8180.     declare @publisher_id smallint
  8181.     declare @subscriber_id smallint
  8182.     declare @active_status tinyint
  8183.     declare @snapshot_bit int
  8184.     declare @undelivered_commands int
  8185.     declare @delivered_commands int
  8186.     declare @delivery_rate float
  8187.     declare @delivery_latency int
  8188.     declare @xact_seqno varbinary(16)
  8189.     declare @agent_id int
  8190.     
  8191.     select @active_status = 2
  8192.     select @snapshot_bit = 0x80000000
  8193.  
  8194.  
  8195.     -- Make sure publisher is defined on distributor
  8196.     --
  8197.     select @publisher_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)
  8198.     if @publisher_id is null
  8199.        return (1)
  8200.  
  8201.     create table #dist_trans (subscriber_id smallint NOT NULL, undelivered_commands int NOT NULL, 
  8202.         delivered_commands int NOT NULL, delivery_rate float NOT NULL, 
  8203.         delivery_latency int NOT NULL)
  8204.  
  8205.     declare hc CURSOR LOCAL FAST_FORWARD FOR select distinct agent_id
  8206.         from MSsubscriptions
  8207.         where
  8208.         publisher_id = @publisher_id and
  8209.         subscriber_id >= 0 and
  8210.         status = 2
  8211.         for read only
  8212.  
  8213.     open hc
  8214.     fetch hc into  @agent_id
  8215.     while (@@fetch_status <> -1)
  8216.     begin
  8217.         -- Get the lastest numbers from distribution_history
  8218.         select  @xact_seqno = NULL
  8219.  
  8220.         -- Get latest seqno, rate and latency
  8221.         set rowcount 1
  8222.         select  @xact_seqno = xact_seqno,
  8223. --              @delivered_commands = delivered_commands,
  8224.                 @delivery_rate = current_delivery_rate,
  8225.                 @delivery_latency = current_delivery_latency
  8226.             -- from MSdistribution_history  (READPAST)
  8227.             from MSdistribution_history 
  8228.             where
  8229.             agent_id = @agent_id and
  8230.             xact_seqno <> 0x0
  8231.             order by timestamp DESC
  8232.         set rowcount 0
  8233.  
  8234.         if @xact_seqno IS NULL
  8235.             select  @xact_seqno = 0x00,
  8236.                     @delivery_rate = 0,
  8237.                     @delivery_latency = 0
  8238.  
  8239.  
  8240.         set rowcount 1
  8241.         select @subscriber_id = subscriber_id FROM MSsubscriptions
  8242.             where agent_id = @agent_id
  8243.         set rowcount 0
  8244.         
  8245.         -- Get the delivered trans number
  8246.         select @delivered_commands = 0
  8247.         select @delivered_commands = isnull(count(*), 0)
  8248.             from
  8249.             -- MSrepl_commands rc (READPAST), MSsubscriptions s
  8250.             MSrepl_commands rc, MSsubscriptions s
  8251.             where
  8252.             /*
  8253.             ** Query from sp_MSget_repl_commands
  8254.             */
  8255.             s.agent_id = @agent_id and
  8256.             s.status = @active_status and
  8257.             rc.publisher_database_id = s.publisher_database_id and
  8258. --          rc.publisher_id = s.publisher_id and
  8259. --          rc.publisher_db = s.publisher_db and
  8260.             rc.xact_seqno <= @xact_seqno and
  8261.             rc.article_id = s.article_id and
  8262.             rc.partial_command = 0
  8263.             and
  8264.             ((rc.xact_seqno >= s.subscription_seqno and (rc.type & @snapshot_bit) <> @snapshot_bit) or
  8265.             rc.xact_seqno = s.subscription_seqno)
  8266.  
  8267.         -- Get the undelivered trans number
  8268.         select @undelivered_commands = 0
  8269.         select @undelivered_commands = isnull(count(*), 0)
  8270.             from
  8271.             -- MSrepl_commands rc (READPAST), MSsubscriptions s
  8272.             MSrepl_commands rc , MSsubscriptions s
  8273.             where
  8274.             /*
  8275.             ** Query from sp_MSget_repl_commands
  8276.             */
  8277.             s.agent_id = @agent_id and
  8278.             s.status = @active_status and
  8279.             rc.publisher_database_id = s.publisher_database_id and
  8280.             rc.xact_seqno > @xact_seqno and
  8281.             rc.article_id = s.article_id and
  8282.             rc.partial_command = 0
  8283.             and
  8284.             ((rc.xact_seqno >= s.subscription_seqno and (rc.type & @snapshot_bit) <> @snapshot_bit) or
  8285.             rc.xact_seqno = s.subscription_seqno)
  8286.  
  8287.         insert into #dist_trans values (@subscriber_id, @undelivered_commands,
  8288.             @delivered_commands, @delivery_rate, @delivery_latency)
  8289.         
  8290.         fetch hc into  @agent_id
  8291.     end
  8292.  
  8293.     close hc
  8294.     deallocate hc
  8295.  
  8296.     select 'subscriber' = srvname, 
  8297.             'delivered commands' = sum(delivered_commands),
  8298.             'undelivered_commands' = sum(undelivered_commands),
  8299.             'delivery_rate' = sum(delivery_rate),
  8300.             'delivery_latency' = (select isnull(avg(delivery_latency), 0) from #dist_trans, master.dbo.sysservers where
  8301.                 srvname = s1.srvname and delivery_latency > 0)
  8302.         from #dist_trans, master.dbo.sysservers s1
  8303.         where subscriber_id = srvid
  8304.         group by srvname
  8305.  
  8306.     drop table #dist_trans
  8307.         
  8308. GO
  8309.  
  8310. raiserror(15339,-1,-1,'sp_MSremove_published_jobs')
  8311. go
  8312. CREATE PROCEDURE sp_MSremove_published_jobs
  8313. @server sysname,
  8314. @database sysname
  8315. AS
  8316.     -- 6.5 publisher and 7.0 publisher will call this
  8317.     -- publisher_database_id will be drop in sp_MSdrop_publication.
  8318.     return(0)
  8319. go
  8320.  
  8321. raiserror(15339,-1,-1,'sp_MSset_snapshot_xact_seqno')
  8322. go
  8323.  
  8324. CREATE PROCEDURE sp_MSset_snapshot_xact_seqno
  8325. @publisher_id int,
  8326. @publisher_db sysname,
  8327. @article_id int, 
  8328. @xact_seqno varbinary(16),
  8329. @reset bit = 0,         /* @reset = 1 is used for Scheduled Snapshot publications by snapshot */
  8330. @publication sysname = NULL,
  8331. @publisher_seqno varbinary(16) = 0x00
  8332. /* 
  8333. ** Required for 6x publishers!
  8334. */
  8335. AS
  8336.  
  8337.     DECLARE @virtual smallint     /* const: virtual subscriber id */
  8338.     DECLARE @virtual_anonymous smallint /* const: virtual anonymous subscriber id */
  8339.     DECLARE @old_xact_seqno varbinary(16)
  8340.     DECLARE @old_publisher_seqno varbinary(16)
  8341.     DECLARE @subscribed tinyint
  8342.     DECLARE @automatic tinyint
  8343.     DECLARE @old_snapshot_seqno_flag bit
  8344.     DECLARE @publication_id int
  8345.  
  8346.     SELECT @virtual = -1
  8347.     SELECT @virtual_anonymous = -2
  8348.     SELECT @subscribed = 1
  8349.     SELECT @automatic = 1
  8350.  
  8351.     -- 6.5 only!!! @publication is not null only if the publisher is 6.5 sever!
  8352.     -- Set the publication_id and sync_type in MSsubscriptions.
  8353.     -- It will be used in sp_MSupdate_subscriptions 
  8354.     IF @publication IS NOT NULL
  8355.     BEGIN
  8356.         -- Get the publication id
  8357.         SELECT @publication_id = publication_id FROM MSpublications
  8358.             WHERE   publisher_id = @publisher_id AND
  8359.                     publisher_db = @publisher_db AND    
  8360.                     publication  = @publication
  8361.  
  8362.         -- Set the pubid and the sync_type
  8363.         -- Avoid update rows with no change to reduce update locks.
  8364.         
  8365.         UPDATE MSsubscriptions SET publication_id = @publication_id
  8366.             WHERE   publisher_id = @publisher_id AND
  8367.                     publisher_db = @publisher_db AND    
  8368.                     article_id  = @article_id and
  8369.                     status = @subscribed and
  8370.                     publication_id <> @publication_id
  8371.         
  8372.         -- Have to do this to avoid no sync subs from 6.5 publisher being
  8373.         -- updated.
  8374.         UPDATE MSsubscriptions SET sync_type = @automatic
  8375.             WHERE   publisher_id = @publisher_id AND
  8376.                     publisher_db = @publisher_db AND    
  8377.                     article_id  = @article_id and
  8378.                     status = @subscribed and
  8379.                     sync_type <> @automatic
  8380.     END
  8381.  
  8382.     begin tran
  8383.     save TRANSACTION MSset_snapshot_xact_seqno
  8384.  
  8385.     /* 
  8386.     ** Set snapshot_xact_seqno for all new subscriptions,
  8387.     ** plus the virtual subscription or all subscriptions if @reset = 1
  8388.     ** Note virtual anonymous subscription will not be set
  8389.     ** (2 virtual subscriptions of anonymous publication will be activated
  8390.     ** immediately without snapshot
  8391.     ** 
  8392.     ** @reset = 1 is used for Scheduled Snapshot publications by snapshot
  8393.     */
  8394.     UPDATE MSsubscriptions SET subscription_seqno = @xact_seqno,
  8395.         publisher_seqno = @publisher_seqno,
  8396.         snapshot_seqno_flag = 1,
  8397.         subscription_time = getdate()
  8398.       WHERE 
  8399.          MSsubscriptions.publisher_id = @publisher_id and
  8400.          MSsubscriptions.publisher_db = @publisher_db and
  8401.          MSsubscriptions.article_id = @article_id and 
  8402.          /* virtual subscriptions are automatic sync type */
  8403.          MSsubscriptions.sync_type = @automatic and 
  8404.          (MSsubscriptions.status = @subscribed or 
  8405.          MSsubscriptions.subscriber_id = @virtual or
  8406.          -- Set for virtual anonymous account if snapshot_seqno_flag
  8407.          -- is 0.
  8408.          -- The virtual anonymous account is activated immediately at subscription
  8409.          -- time for no init option for anonymous agent.
  8410.          (MSsubscriptions.subscriber_id = @virtual_anonymous and 
  8411.          MSsubscriptions.snapshot_seqno_flag = 0) or
  8412.          @reset = 1) 
  8413.  
  8414.     IF @@ERROR <> 0
  8415.     BEGIN
  8416.         if @@trancount > 0
  8417.         begin
  8418.             ROLLBACK TRANSACTION MSset_snapshot_xact_seqno
  8419.             commit tran
  8420.         end
  8421.         RETURN (1)
  8422.     END
  8423.  
  8424.     COMMIT TRANSACTION
  8425. GO
  8426.  
  8427.  
  8428. raiserror(15339,-1,-1,'sp_MSdrop_article')
  8429. go
  8430. CREATE PROCEDURE sp_MSdrop_article
  8431. @publisher sysname,
  8432. @publisher_db sysname,
  8433. @publication sysname,
  8434. @article sysname
  8435.  
  8436. as
  8437.  
  8438.     set nocount on
  8439.  
  8440.     declare @publisher_id smallint
  8441.     declare @publication_id int
  8442.     declare @article_id int
  8443.     declare @retcode int
  8444.     declare @thirdparty_flag bit
  8445.     declare @immediate_sync bit
  8446.  
  8447.     -- Check if publisher is a defined as a distribution publisher in the current database
  8448.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  8449.     if @retcode <> 0
  8450.     begin
  8451.         return(1)
  8452.     end
  8453.  
  8454.     -- Make sure publication exists
  8455.     select @publication_id = publication_id, @thirdparty_flag = thirdparty_flag,
  8456.         @immediate_sync = immediate_sync
  8457.         from MSpublications where 
  8458.         publication = @publication and
  8459.         publisher_id = @publisher_id and 
  8460.         publisher_db = @publisher_db
  8461.     if @publication_id is NULL
  8462.     begin
  8463.         raiserror(20026, 16, -1, @publication)
  8464.         return (1)
  8465.     end
  8466.  
  8467.     -- Make sure article exists
  8468.     select @article_id = article_id from MSarticles where 
  8469.         publication_id = @publication_id and
  8470.         publisher_id = @publisher_id and 
  8471.         publisher_db = @publisher_db and 
  8472.         article = @article
  8473.     if @article_id is NULL
  8474.     begin
  8475.         if @thirdparty_flag = 1
  8476.         begin
  8477.             raiserror(20027, 16, -1, @article)
  8478.             return (1)
  8479.         end
  8480.         else
  8481.             return (0)
  8482.     end
  8483.  
  8484.     -- Check to make sure that there are no subscriptions on the article
  8485.     if exists (select * from MSsubscriptions where 
  8486.         publisher_id = @publisher_id and
  8487.         publisher_db = @publisher_db and
  8488.         publication_id = @publication_id and
  8489.         article_id = @article_id and
  8490.         subscriber_id >= 0)             -- ignore virtual subscriptions
  8491.     begin
  8492.         raiserror(14046, 16, -1)
  8493.         return(1)
  8494.     end
  8495.  
  8496.     begin tran
  8497.     save tran MSdrop_article
  8498.  
  8499.     -- For third party publications drop immediate sync and anonymous virtual subscriptions
  8500.     -- SQL Server publications will do this via RPC calls to sp_MSadd_subscription
  8501.     if @thirdparty_flag = 1 and @immediate_sync = 1
  8502.     begin
  8503.         begin
  8504.             exec @retcode = dbo.sp_MSdrop_subscription
  8505.                 @publisher = @publisher,
  8506.                 @publisher_db = @publisher_db,
  8507.                 @publication = @publication,
  8508.                 @article_id = @article_id,
  8509.                 @subscriber = NULL                  -- virtual subscription
  8510.             if @retcode <> 0 or @@error <> 0
  8511.             begin
  8512.                 if @@trancount > 0
  8513.                 begin
  8514.                     rollback tran MSdrop_article
  8515.                     commit tran
  8516.                 end
  8517.                 return (1)
  8518.             end
  8519.         end
  8520.     end
  8521.  
  8522.     delete from MSarticles where
  8523.         publisher_id = @publisher_id and
  8524.         publisher_db = @publisher_db and
  8525.         publication_id = @publication_id and
  8526.         article_id = @article_id
  8527.     if @@error <> 0
  8528.     begin
  8529.         if @@trancount > 0
  8530.         begin
  8531.             rollback tran MSdrop_article
  8532.             commit tran
  8533.         end
  8534.         return (1)
  8535.     end
  8536.  
  8537.     commit tran
  8538. go
  8539.  
  8540. raiserror(15339,-1,-1,'sp_MSdrop_snapshot_agent')
  8541. GO
  8542. CREATE PROCEDURE sp_MSdrop_snapshot_agent (
  8543.     @publisher sysname,
  8544.     @publisher_db sysname,
  8545.     @publication sysname
  8546. ) AS
  8547.  
  8548.  
  8549.     SET NOCOUNT ON
  8550.  
  8551.     /*
  8552.     ** Declarations.
  8553.     */
  8554.     DECLARE @retcode    int
  8555.     DECLARE @job_id     binary(16)
  8556.     DECLARE @local_job  bit
  8557.     DECLARE @publisher_id smallint
  8558.     DECLARE @name       nvarchar(100)
  8559.     DECLARE @agent_id   int
  8560.  
  8561.     /*
  8562.     ** Initializations
  8563.     */
  8564.     select @publisher_id = srvid from master..sysservers where
  8565.         UPPER(srvname) = UPPER(@publisher)
  8566.  
  8567.  
  8568.  
  8569.     SELECT @job_id = job_id, @local_job = local_job, @name = name, @agent_id = id  FROM MSsnapshot_agents WHERE
  8570.         publisher_id = @publisher_id AND
  8571.         publisher_db = @publisher_db AND
  8572.         publication = @publication
  8573.  
  8574.     -- Delete Perfmon instance
  8575.     dbcc deleteinstance ("SQL Replication Snapshot", @name)
  8576.  
  8577.     -- Return if not exists
  8578.     IF @local_job IS NULL
  8579.         RETURN(0)
  8580.  
  8581.     BEGIN TRAN
  8582.  
  8583.     IF @local_job = 1
  8584.     BEGIN
  8585.         IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE job_id = @job_id)
  8586.         BEGIN
  8587.             EXEC @retcode = msdb.dbo.sp_delete_job @job_id = @job_id
  8588.             IF @@ERROR <> 0 or @retcode <> 0
  8589.                 GOTO UNDO
  8590.         END
  8591.     END
  8592.  
  8593.     DELETE MSsnapshot_agents WHERE id = @agent_id
  8594.     IF @@ERROR <> 0 
  8595.         GOTO UNDO
  8596.  
  8597.     -- Remove history
  8598.     DELETE MSsnapshot_history WHERE agent_id = @agent_id
  8599.     IF @@ERROR <> 0 
  8600.         GOTO UNDO
  8601.  
  8602.     IF @@ERROR <> 0 
  8603.         GOTO UNDO
  8604.  
  8605.     -- Update global replication status table
  8606.     EXEC dbo.sp_MSupdate_replication_status
  8607.         @publisher,
  8608.         @publisher_db,
  8609.         @publication,
  8610.         @agent_type = 1,
  8611.         @agent_name = @name,
  8612.         @status = -1    -- delete status
  8613.  
  8614.     COMMIT TRAN
  8615.  
  8616.     RETURN(0)
  8617.  
  8618. UNDO:
  8619.     if @@TRANCOUNT = 1
  8620.         ROLLBACK TRAN
  8621.     else
  8622.         COMMIT TRAN
  8623.     return(1)
  8624. GO
  8625.  
  8626.  
  8627. raiserror(15339,-1,-1,'sp_MSdrop_logreader_agent')
  8628. GO
  8629. CREATE PROCEDURE sp_MSdrop_logreader_agent (
  8630.     @publisher sysname,
  8631.     @publisher_db sysname,
  8632.     @publication sysname  --Only used by 3rd party publisher
  8633. ) AS
  8634.  
  8635.  
  8636.     SET NOCOUNT ON
  8637.  
  8638.     /*
  8639.     ** Declarations.
  8640.     */
  8641.     DECLARE @retcode    int
  8642.     DECLARE @job_id     binary(16)
  8643.     DECLARE @local_job  bit
  8644.     DECLARE @publisher_id smallint
  8645.     DECLARE @name       nvarchar(100)
  8646.     DECLARE @agent_id   int
  8647.  
  8648.     /*
  8649.     ** Initializations
  8650.     */
  8651.     select @publisher_id = srvid from master..sysservers where
  8652.         UPPER(srvname) = UPPER(@publisher)
  8653.  
  8654.  
  8655.     SELECT @job_id = job_id, @local_job = local_job, @name = name, @agent_id = id FROM MSlogreader_agents WHERE
  8656.         publisher_id = @publisher_id AND
  8657.         publisher_db = @publisher_db AND
  8658.         publication = @publication
  8659.  
  8660.     -- Delete Perfmon instance
  8661.     dbcc deleteinstance ("SQL Replication Logreader", @name)
  8662.  
  8663.     -- Return if not exists
  8664.     IF @local_job IS NULL
  8665.         RETURN(0)
  8666.  
  8667.     BEGIN TRAN
  8668.  
  8669.     IF @local_job = 1
  8670.     BEGIN
  8671.         IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE job_id = @job_id)
  8672.         BEGIN
  8673.             EXEC @retcode = msdb.dbo.sp_delete_job @job_id = @job_id
  8674.             IF @@ERROR <> 0 or @retcode <> 0
  8675.                 GOTO UNDO
  8676.         END
  8677.     END
  8678.  
  8679.     DELETE MSlogreader_agents WHERE id = @agent_id
  8680.     IF @@ERROR <> 0 
  8681.         GOTO UNDO
  8682.  
  8683.     -- Remove history
  8684.     DELETE MSlogreader_history WHERE
  8685.         agent_id = @agent_id
  8686.  
  8687.     IF @@ERROR <> 0 
  8688.         GOTO UNDO
  8689.  
  8690.     -- Update global replication status table
  8691.     EXEC dbo.sp_MSupdate_replication_status
  8692.         @publisher,
  8693.         @publisher_db,
  8694.         @publication,
  8695.         @agent_type = 2,
  8696.         @agent_name = @name,
  8697.         @status = -1    -- delete status
  8698.  
  8699.     COMMIT TRAN
  8700.  
  8701.     RETURN(0)
  8702.  
  8703. UNDO:
  8704.     if @@TRANCOUNT = 1
  8705.         ROLLBACK TRAN
  8706.     else
  8707.         COMMIT TRAN
  8708.     return(1)
  8709. GO
  8710.  
  8711. raiserror(15339,-1,-1,'sp_MSdrop_publication')
  8712. go
  8713. CREATE PROCEDURE sp_MSdrop_publication
  8714. @publisher sysname,
  8715. @publisher_db sysname,
  8716. @publication sysname
  8717. as
  8718.  
  8719.     set nocount on
  8720.  
  8721.     declare @publisher_id smallint
  8722.     declare @publication_id int
  8723.     declare @retcode int
  8724.     declare @article sysname
  8725.     declare @thirdparty_flag bit
  8726.     DECLARE @working_dir nvarchar(255)
  8727.     DECLARE @working_dir_drive nvarchar(255)
  8728.     DECLARE @pub_dir nvarchar(255)
  8729.  
  8730.  
  8731.     -- Check if publisher is a defined as a distribution publisher in the current database
  8732.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  8733.     if @retcode <> 0
  8734.     begin
  8735.         return(1)
  8736.     end
  8737.  
  8738.     -- Make sure publication exists
  8739.     select @publication_id = publication_id, @thirdparty_flag = thirdparty_flag 
  8740.         from MSpublications where publication = @publication and
  8741.         publisher_id = @publisher_id and publisher_db = @publisher_db
  8742.     if @publication_id is NULL
  8743.     begin
  8744.         -- We don't know whether or not it is a third party or not so we can not 
  8745.         -- return error.
  8746.         -- raiserror(20026, 16, -1, @publication)
  8747.         -- return (1)
  8748.         return (0)
  8749.     end
  8750.  
  8751.     -- Make sure that there are no subscriptions on the publication.
  8752.     if exists (select * from MSsubscriptions s, MSpublications p where 
  8753.         p.publisher_id = @publisher_id and
  8754.         p.publisher_db = @publisher_db and
  8755.         p.publication = @publication and
  8756.         s.publisher_id = @publisher_id and
  8757.         s.publisher_db = @publisher_db and
  8758.         s.publication_id = p.publication_id and
  8759.         s.subscriber_id >= 0)               -- ignore virtual subscriptions
  8760.     begin
  8761.         raiserror(14005, 16, -1)
  8762.         return(1)
  8763.     end
  8764.  
  8765.     SELECT @working_dir = working_directory FROM msdb..MSdistpublishers
  8766.         where UPPER(name) = UPPER(@publisher)
  8767.  
  8768.     IF @working_dir IS NOT NULL
  8769.     BEGIN
  8770.         /* 
  8771.         ** We have to convert UNC to drive, otherwise will get 'Access denied' error in xp_cmdshell
  8772.         */
  8773.         EXEC master.dbo.sp_MSunc_to_drive @unc_path = @working_dir, 
  8774.             @local_server = @@SERVERNAME, @local_path = @working_dir_drive OUTPUT
  8775.  
  8776.         /*
  8777.         ** Delete publication directory in the distributor's directory.
  8778.         */
  8779.         SELECT @pub_dir = 'rmdir /S /Q ' + '"' +
  8780.                     @working_dir_drive + '\unc\' + 
  8781.                     @@SERVERNAME + '_' +
  8782.                     @publisher_db + '_' +
  8783.                     @publication + '"'
  8784.         EXECUTE  master..xp_cmdshell @pub_dir, NO_OUTPUT
  8785.         -- Ignore retcode error since the directory may not exist
  8786.         IF @@ERROR <> 0 
  8787.             RETURN(1)
  8788.    
  8789.         SELECT @pub_dir = 'rmdir /S /Q ' + '"' + 
  8790.                     @working_dir + '\inet\' + 
  8791.                     @@SERVERNAME + '_' +
  8792.                     @publisher_db + '_' +
  8793.                     @publication + '"'
  8794.         EXECUTE master..xp_cmdshell @pub_dir, NO_OUTPUT
  8795.         -- Ignore retcode error since the directory may not exist
  8796.         IF @@ERROR <> 0 
  8797.             RETURN(1)
  8798.     END
  8799.  
  8800.     begin tran
  8801.     save tran MSdrop_publication
  8802.  
  8803.     -- Delete all articles if a third party publication
  8804.     if @thirdparty_flag = 1 
  8805.     begin
  8806.         -- Delete all articles in the publication
  8807.         declare hCarticles CURSOR LOCAL FAST_FORWARD FOR select article from MSarticles where 
  8808.             publisher_id = @publisher_id and
  8809.             publisher_db = @publisher_db and
  8810.             publication_id = 
  8811.                 (select publication_id from MSpublications where 
  8812.                     publisher_id = @publisher_id and
  8813.                     publisher_db = @publisher_db and
  8814.                     publication = @publication)
  8815.         open hCarticles
  8816.         fetch hCarticles into @article
  8817.         while (@@fetch_status <> -1)
  8818.         begin
  8819.             exec @retcode = dbo.sp_MSdrop_article @publisher, @publisher_db, @publication, @article
  8820.             if @retcode != 0 or @@error != 0
  8821.             begin
  8822.                 close hCarticles
  8823.                 deallocate hCarticles
  8824.                 if @@trancount > 0
  8825.                 begin
  8826.                     rollback tran MSdrop_publication
  8827.                     commit tran
  8828.                 end
  8829.                 return (1)
  8830.             end
  8831.                 
  8832.             fetch hCarticles into @article
  8833.         end
  8834.         close hCarticles
  8835.         deallocate hCarticles
  8836.     end
  8837.  
  8838.     delete from MSpublications where 
  8839.         publisher_id = @publisher_id and
  8840.         publisher_db = @publisher_db and
  8841.         publication = @publication
  8842.     if @@error <> 0
  8843.     begin
  8844.         if @@trancount > 0
  8845.         begin
  8846.             rollback tran MSdrop_publication
  8847.             commit tran
  8848.         end
  8849.         raiserror (14006, 16, -1)
  8850.         return (1)
  8851.     end
  8852.  
  8853.     -- Drop snapshot agent
  8854.     exec @retcode = dbo.sp_MSdrop_snapshot_agent
  8855.             @publisher = @publisher,
  8856.             @publisher_db = @publisher_db,
  8857.             @publication = @publication
  8858.     if @@ERROR<> 0 or @retcode <> 0
  8859.     begin
  8860.         if @@trancount > 0
  8861.         begin
  8862.             rollback tran MSdrop_publication
  8863.             commit tran
  8864.         end
  8865.         return (1)
  8866.     end
  8867.  
  8868.     -- Drop the logreader agent if
  8869.     -- 1. thirdparty publisher OR 
  8870.     -- 2. no publication left in the publisher database
  8871.     if @thirdparty_flag = 1 OR
  8872.         not exists (select * from MSpublications where 
  8873.             publisher_id = @publisher_id and
  8874.             publisher_db = @publisher_db)
  8875.     begin
  8876.         exec @retcode = dbo.sp_MSdrop_logreader_agent
  8877.                 @publisher = @publisher,
  8878.                 @publisher_db = @publisher_db,
  8879.                 @publication = @publication
  8880.         if @@ERROR<> 0 or @retcode <> 0
  8881.         begin
  8882.             if @@trancount > 0
  8883.             begin
  8884.                 rollback tran MSdrop_publication
  8885.                 commit tran
  8886.             end
  8887.             return (1)
  8888.         end
  8889.     end
  8890.  
  8891.     -- Delete anonymous agents
  8892.     delete MSdistribution_agents where
  8893.         publisher_id = @publisher_id and
  8894.         publisher_db = @publisher_db and
  8895.         publication = @publication
  8896.     if @@ERROR<> 0 or @retcode <> 0
  8897.     begin
  8898.         if @@trancount > 0
  8899.             rollback tran MSdrop_publication
  8900.         return (1)
  8901.     end
  8902.  
  8903.     delete MSmerge_agents where
  8904.         publisher_id = @publisher_id and
  8905.         publisher_db = @publisher_db and
  8906.         publication = @publication
  8907.     if @@ERROR<> 0 or @retcode <> 0
  8908.     begin
  8909.         if @@trancount > 0
  8910.             rollback tran MSdrop_publication
  8911.         return (1)
  8912.     end
  8913.  
  8914.     -- Cleanup publication access list table
  8915.     delete MSpublication_access where
  8916.         publication_id = @publication_id
  8917.     if @@ERROR<> 0 or @retcode <> 0
  8918.     begin
  8919.         if @@trancount > 0
  8920.             rollback tran MSdrop_publication
  8921.         return (1)
  8922.     end
  8923.  
  8924.     -- Remove publisher_id, publisher_db pair if no other publication is using it.  This is used
  8925.     -- to store a publisher_database_id in the MSrepl_transactions and MSrepl_commands table.
  8926.     if not exists (select * from MSpublications where publisher_id = @publisher_id and
  8927.         publisher_db = @publisher_db)
  8928.     begin
  8929.         declare @publisher_database_id int
  8930.  
  8931.         select @publisher_database_id = id from MSpublisher_databases where 
  8932.             publisher_id = @publisher_id and 
  8933.             publisher_db = @publisher_db
  8934.  
  8935.         delete from MSpublisher_databases where 
  8936.             publisher_id = @publisher_id and publisher_db = @publisher_db
  8937.         if @@error <> 0
  8938.         begin
  8939.             if @@trancount > 0
  8940.             begin
  8941.                 rollback tran MSdrop_publication
  8942.                 commit tran
  8943.             end
  8944.             return (1)
  8945.         end
  8946.  
  8947.         -- Cleaning up MSrepl_originators
  8948.         delete MSrepl_originators where
  8949.             publisher_database_id = @publisher_database_id
  8950.         if @@error <> 0
  8951.         begin
  8952.             if @@trancount > 0
  8953.                 rollback tran MSdrop_publication
  8954.             return (1)
  8955.         end
  8956.  
  8957.     end
  8958.  
  8959.     commit tran
  8960. go
  8961. raiserror(15339,-1,-1,'sp_MSadd_snapshot_agent')
  8962. GO
  8963. CREATE PROCEDURE sp_MSadd_snapshot_agent (
  8964.     @name nvarchar(100) = NULL,
  8965.     @publisher sysname,
  8966.     @publisher_db sysname,
  8967.     @publication sysname,  
  8968.     @publication_type int = 0,              -- 0 Transactional 1 Snapshot 2 Merge
  8969.     @local_job bit,  
  8970.     @freqtype  int = 4 ,                  /* 4== Daily */
  8971.     @freqinterval int  = 1,             /* Every day */
  8972.     @freqsubtype int =  4,                 /* Sub interval = Minute */
  8973.     @freqsubinterval int = 5,              /* Every five minutes */
  8974.     @freqrelativeinterval int = 1, 
  8975.     @freqrecurrencefactor int = 0, 
  8976.     @activestartdate int = 0,             /* 12:00 am - 11:59 pm */
  8977.     @activeenddate int =99991231 ,         /* No start date */    
  8978.     @activestarttimeofday int = 0,         
  8979.     @activeendtimeofday int = 235959,     /* No end time */    
  8980.     @command nvarchar(4000) = NULL,
  8981.     @job_existing bit = 0,   -- for 6x publisher
  8982.     @snapshot_jobid binary(16) = NULL OUTPUT
  8983. ) AS
  8984.  
  8985.  
  8986.     SET NOCOUNT ON
  8987.  
  8988.     /*
  8989.     ** Declarations.
  8990.     */
  8991.     DECLARE @retcode            int
  8992.     DECLARE @publisher_id       smallint
  8993.     DECLARE @profile_id         int
  8994.     DECLARE @snapshot_type      int
  8995.     DECLARE @databasename       sysname
  8996.     DECLARE @agent_id           int
  8997.  
  8998.     DECLARE @distributor_security_mode      int                     /* 0 standard; 1 integrated */
  8999.     DECLARE @distributor_login              sysname 
  9000.     DECLARE @distributor_password           sysname
  9001.     DECLARE @category_name      sysname
  9002.     DECLARE @platform_nt        binary
  9003.  
  9004.     /*
  9005.     ** Initializations
  9006.     */
  9007.     select @platform_nt = 0x1
  9008.  
  9009.     select @publisher_id = srvid from master..sysservers where
  9010.         UPPER(srvname) = UPPER(@publisher)
  9011.  
  9012.     -- Always use integrated security on winNT
  9013.     if (@platform_nt = platform() & @platform_nt)
  9014.         set @distributor_security_mode = 1
  9015.     else
  9016.     begin
  9017.         select  @distributor_security_mode = 0,
  9018.                 @distributor_login  = login,
  9019.                 @distributor_password = password
  9020.             from msdb..MSdistpublishers where UPPER(name) = UPPER(@@servername)
  9021.     end
  9022.  
  9023.     select @command = @command + ' -DistributorSecurityMode ' + 
  9024.         convert(nvarchar(10),@distributor_security_mode) +  ' ' 
  9025.     if @distributor_security_mode <> 1
  9026.     begin
  9027.         if @distributor_login is not NULL
  9028.             select @command = @command + '-DistributorLogin ' + @distributor_login + ' '
  9029.         if @distributor_password is not NULL
  9030.             select @command = @command + '-DistributorEncryptedPassword ' + quotename(@distributor_password) + ' '
  9031.     end
  9032.  
  9033.     BEGIN TRAN
  9034.     
  9035.     -- If creating locally, try to drop it first
  9036.     IF @local_job = 1 and @job_existing = 0
  9037.     begin
  9038.         EXEC dbo.sp_MSdrop_snapshot_agent 
  9039.             @publisher = @publisher,
  9040.             @publisher_db = @publisher_db,
  9041.             @publication = @publication  
  9042.         IF @@ERROR <> 0
  9043.             GOTO UNDO
  9044.     end
  9045.  
  9046.     /* Code for snapshot agent type in MSagent_profiles */
  9047.     SELECT @snapshot_type = 1
  9048.  
  9049.     -- Get the default profile ID for the snapshot agent type. If a third party publication
  9050.     -- no profile is used.
  9051.     if exists (select * from MSpublications where 
  9052.                 publisher_id = @publisher_id and
  9053.                 publisher_db = @publisher_db and
  9054.                 publication = @publication and
  9055.                 thirdparty_flag = 1)
  9056.     begin
  9057.         set @profile_id = 0
  9058.     end
  9059.     else
  9060.     begin
  9061.         SELECT @profile_id = profile_id FROM msdb..MSagent_profiles WHERE 
  9062.             agent_type = @snapshot_type and
  9063.             def_profile = 1
  9064.     end
  9065.  
  9066.     -- Get the job id if it already exists
  9067.     if @local_job = 1 and @job_existing = 1
  9068.     begin
  9069.         select @snapshot_jobid = job_id from msdb..sysjobs_view where 
  9070.             job_id = @snapshot_jobid and
  9071.             originating_server = '(local)'
  9072.         if @snapshot_jobid IS NULL
  9073.         begin
  9074.             -- Message from msdb.dbo.sp_verify_job_identifiers
  9075.             RAISERROR(14262, -1, -1, 'Job', @name)          
  9076.             GOTO UNDO
  9077.         end
  9078.  
  9079.         --Drop the agent entry if it already exists, and recreate
  9080.         delete from MSsnapshot_agents where job_id = @snapshot_jobid
  9081.     end
  9082.  
  9083.     /* 
  9084.     ** Insert row
  9085.     */
  9086.     INSERT INTO MSsnapshot_agents (name, publisher_id, publisher_db, publication, publication_type,
  9087.                             local_job, profile_id)
  9088.          VALUES ('',@publisher_id, @publisher_db, @publication, @publication_type, @local_job, @profile_id)
  9089.     IF @@ERROR <> 0
  9090.         GOTO UNDO
  9091.  
  9092.     set @agent_id = @@IDENTITY
  9093.         
  9094.     IF @name IS NULL
  9095.         SELECT @name = CONVERT(nvarchar(28),@publisher ) + '-' + CONVERT(nvarchar(28),@publisher_db) + '-' + 
  9096.                         CONVERT(nvarchar(28),@publication) + '-'  + CONVERT(nvarchar, @@IDENTITY)
  9097.     
  9098.     -- Add Perfmon instance
  9099.     dbcc addinstance ("SQL Replication Snapshot", @name)
  9100.  
  9101.     IF @local_job = 1 and @job_existing = 0
  9102.     BEGIN
  9103.  
  9104.     -- ********WORKAROUND********
  9105.         DECLARE @nullchar nchar(20)
  9106.         SELECT @nullchar = NULL
  9107.     -- ********WORKAROUND********
  9108.  
  9109.         set @databasename = db_name()
  9110.         -- Get Snapshot category name (assumes category_id = 15)
  9111.         select @category_name = name FROM msdb.dbo.syscategories where category_id = 15
  9112.  
  9113.         EXECUTE @retcode = dbo.sp_MSadd_repl_job 
  9114.             @name = @name, 
  9115.             @subsystem = 'Snapshot', 
  9116.             @server = @publisher, 
  9117.             @databasename = @databasename, 
  9118.             @enabled = 1, 
  9119.             @freqtype = @freqtype, 
  9120.             @freqinterval = @freqinterval, 
  9121.             @freqsubtype = @freqsubtype, 
  9122.             @freqsubinterval = @freqsubinterval, 
  9123.             @freqrelativeinterval = @freqrelativeinterval, 
  9124.             @freqrecurrencefactor = @freqrecurrencefactor, 
  9125.             @activestartdate = @activestartdate, 
  9126.             @activeenddate = @activeenddate, 
  9127.             @activestarttimeofday = @activestarttimeofday, 
  9128.             @activeendtimeofday = @activeendtimeofday, 
  9129.             @nextrundate = 0,
  9130.             @nextruntime = 0,
  9131.             @runpriority = 0,
  9132.             @emailoperatorname = @nullchar,
  9133.             @retryattempts = 10, 
  9134.             @retrydelay = 1, 
  9135.             @command = @command, 
  9136.             @loghistcompletionlevel = 0, 
  9137.             @emailcompletionlevel = 0, 
  9138.             @description = @nullchar,
  9139.             @tagadditionalinfo = @nullchar,
  9140.             @tagobjectid = 0, 
  9141.             @tagobjecttype = 0, 
  9142.             @category_name = @category_name,
  9143.             @failure_detection = 1,
  9144.             @agent_id = @agent_id,
  9145.             @job_id = @snapshot_jobid OUTPUT
  9146.  
  9147.   
  9148.        IF @@ERROR <> 0 or @retcode <> 0
  9149.             GOTO UNDO
  9150.     END
  9151.  
  9152. /* Moved up
  9153.     -- Get the job id if it already exists
  9154.     if @local_job = 1 and @job_existing = 1 
  9155.     begin
  9156.         select @snapshot_jobid = job_id from msdb..sysjobs_view where 
  9157.             job_id = @snapshot_jobid and
  9158.             originating_server = '(local)'
  9159.         if @snapshot_jobid IS NULL
  9160.         begin
  9161.             -- Message from msdb.dbo.sp_verify_job_identifiers
  9162.             RAISERROR(14262, -1, -1, 'Job', @name)          
  9163.             GOTO UNDO
  9164.         end
  9165.     end
  9166. */
  9167.  
  9168.     -- Generate a job GUID for remote agents. This will be used by the UI to uniquely
  9169.     -- identify rows returned by the enums
  9170.     if @local_job = 0
  9171.     begin
  9172.         set @snapshot_jobid = newid();
  9173.     end
  9174.  
  9175.     UPDATE MSsnapshot_agents SET name = @name,
  9176.         job_id = @snapshot_jobid WHERE
  9177.         id = @agent_id
  9178.     IF @@ERROR <> 0
  9179.         GOTO UNDO
  9180.  
  9181.     -- Update global replication status table
  9182.     EXEC dbo.sp_MSupdate_replication_status
  9183.         @publisher,
  9184.         @publisher_db,
  9185.         @publication,
  9186.         @publication_type,
  9187.         @agent_type = 1,
  9188.         @agent_name = @name,
  9189.         @status = 0     -- not running status
  9190.  
  9191.     COMMIT TRAN
  9192.  
  9193.     RETURN(0)
  9194.  
  9195. UNDO:
  9196.     if @@TRANCOUNT = 1
  9197.         ROLLBACK TRAN
  9198.     else
  9199.         COMMIT TRAN
  9200.     return(1)
  9201. GO
  9202.  
  9203. raiserror(15339,-1,-1,'sp_MSadd_logreader_agent')
  9204. GO
  9205. CREATE PROCEDURE sp_MSadd_logreader_agent (
  9206.     @name nvarchar(100) = NULL,
  9207.     @publisher sysname,
  9208.     @publisher_db sysname,
  9209.     @publication sysname,   --Only used by 3rd party publisher
  9210.     @local_job bit,
  9211.     @job_existing bit = 0,
  9212.     @job_id binary(16) = NULL
  9213. ) AS
  9214.  
  9215.  
  9216.     SET NOCOUNT ON
  9217.  
  9218.     /*
  9219.     ** Declarations.
  9220.     */
  9221.     DECLARE @retcode            int
  9222.     DECLARE @agent_args         nvarchar(255)
  9223.     DECLARE @publisher_id       smallint
  9224.     DECLARE @profile_id         int
  9225.     DECLARE @logreader_type     int
  9226.     DECLARE @databasename       sysname
  9227.     DECLARE @agent_id           int
  9228.     DECLARE @distributor_security_mode      int                     /* 0 standard; 1 integrated */
  9229.     DECLARE @distributor_login              sysname 
  9230.     DECLARE @distributor_password           sysname
  9231.     DECLARE @category_name      sysname
  9232.     DECLARE @platform_nt binary
  9233.  
  9234.     /*
  9235.     ** Initializations
  9236.     */
  9237.     select @platform_nt = 0x1
  9238.  
  9239.     select @publisher_id = srvid from master..sysservers where
  9240.         UPPER(srvname) = UPPER(@publisher)
  9241.     
  9242.     -- Always use integrated security on winNT
  9243.     if (@platform_nt = platform() & @platform_nt)
  9244.         set @distributor_security_mode = 1
  9245.     else
  9246.     begin
  9247.         select  @distributor_security_mode = 0,
  9248.                 @distributor_login  = login,
  9249.                 @distributor_password = password
  9250.             from msdb..MSdistpublishers where UPPER(name) = UPPER(@@servername)
  9251.     end
  9252.  
  9253.     BEGIN TRAN
  9254.  
  9255.     -- If creating locally, try to drop it first
  9256.     IF @local_job = 1 and @job_existing = 0
  9257.     begin
  9258.         EXEC dbo.sp_MSdrop_logreader_agent 
  9259.             @publisher = @publisher,
  9260.             @publisher_db = @publisher_db,
  9261.             @publication = @publication  
  9262.         IF @@ERROR <> 0
  9263.             GOTO UNDO
  9264.     end
  9265.  
  9266.     /* Code for log reader agent type in MSagent_profiles */
  9267.     SELECT @logreader_type = 2
  9268.  
  9269.     -- Get the default profile ID for the logreader agent type. If a third party publication
  9270.     -- no profile is used.
  9271.     if exists (select * from MSpublications where 
  9272.                 publisher_id = @publisher_id and
  9273.                 publisher_db = @publisher_db and
  9274.                 publication = @publication and
  9275.                 thirdparty_flag = 1)
  9276.     begin
  9277.         set @profile_id = 0
  9278.     end
  9279.     else
  9280.     begin
  9281.         SELECT @profile_id = profile_id FROM msdb..MSagent_profiles WHERE 
  9282.             agent_type = @logreader_type and
  9283.             def_profile = 1
  9284.     end
  9285.  
  9286.     /* 
  9287.     ** Insert row
  9288.     */
  9289.     INSERT INTO MSlogreader_agents (name, publisher_id, publisher_db, publication, 
  9290.                     local_job, profile_id)
  9291.          VALUES ('',@publisher_id, @publisher_db, @publication, @local_job, @profile_id)
  9292.     IF @@ERROR <> 0
  9293.         GOTO UNDO
  9294.  
  9295.     set @agent_id = @@IDENTITY
  9296.         
  9297.     IF @name IS NULL
  9298.         SELECT @name = CONVERT(nvarchar(43),@publisher ) + '-' + CONVERT(nvarchar(43),@publisher_db) + '-' + CONVERT(nvarchar, @@IDENTITY)
  9299.     
  9300.     -- Add Perfmon instance
  9301.     dbcc addinstance ("SQL Replication Logreader", @name)
  9302.  
  9303.     IF @local_job = 1 and @job_existing = 0
  9304.     BEGIN            
  9305.         SELECT @agent_args = '-Publisher ' + QUOTENAME(@publisher)
  9306.         SELECT @agent_args = @agent_args + ' -PublisherDB ' + QUOTENAME(@publisher_db)
  9307.         SELECT @agent_args = @agent_args + ' -Distributor ' + QUOTENAME(@@SERVERNAME)
  9308.  
  9309.         select @agent_args = @agent_args + ' -DistributorSecurityMode ' + 
  9310.             convert(nvarchar(10),@distributor_security_mode) +  ' ' 
  9311.         if @distributor_security_mode <> 1
  9312.         begin
  9313.             if @distributor_login is not NULL
  9314.                 select @agent_args = @agent_args + '-DistributorLogin ' + @distributor_login + ' '
  9315.             if @distributor_password is not NULL
  9316.                 select @agent_args = @agent_args + '-DistributorEncryptedPassword ' + quotename(@distributor_password) + ' '
  9317.         end
  9318.  
  9319. --    *******WORKAROUND*******
  9320.         DECLARE @nullchar nchar(20)
  9321.         SELECT @nullchar = NULL
  9322. --    *******WORKAROUND*******
  9323.  
  9324.         set @databasename = db_name()
  9325.         -- Get Logreader category name (assumes category_id = 13)
  9326.         select @category_name = name FROM msdb.dbo.syscategories where category_id = 13
  9327.  
  9328.         EXECUTE @retcode = dbo.sp_MSadd_repl_job
  9329.         @name = @name,
  9330.         @subsystem = 'LogReader',
  9331.         @server = @publisher,
  9332.         @databasename = @databasename,
  9333.         @enabled = 1,
  9334.         @freqtype = 64,       /* Auto-Start */
  9335.         @freqinterval                   = 1,
  9336.         @freqsubtype                    = 1,
  9337.         @freqsubinterval                = 1,
  9338.         @freqrelativeinterval= 1,
  9339.         @freqrecurrencefactor   = 1,
  9340.         @activestartdate                = 0,
  9341.         @activeenddate                  = 0,
  9342.         @activestarttimeofday   = 0,
  9343.         @activeendtimeofday     = 0,
  9344.         @nextrundate                    = 12355,
  9345.         @nextruntime                    = 13423,
  9346.         @runpriority                    = 0,
  9347.         @emailoperatorname              = @nullchar,
  9348.         @retryattempts = 10,            
  9349.         @retrydelay = 1,    
  9350.         @command = @agent_args,
  9351.         @loghistcompletionlevel = 0,
  9352.         @category_name = @category_name,
  9353.         @failure_detection = 1,
  9354.         @agent_id = @agent_id,
  9355.         @job_id = @job_id OUTPUT
  9356.  
  9357.   
  9358.        IF @@ERROR <> 0 or @retcode <> 0
  9359.             GOTO UNDO
  9360.     END
  9361.  
  9362.     if @local_job = 1 and @job_existing = 1 
  9363.     begin
  9364.         select @job_id = job_id from msdb..sysjobs_view where 
  9365.             job_id = @job_id and
  9366.             originating_server = '(local)'
  9367.         if @job_id IS NULL
  9368.         begin
  9369.             -- Message from msdb.dbo.sp_verify_job_identifiers
  9370.             RAISERROR(14262, -1, -1, 'Job', @name)          
  9371.             GOTO UNDO
  9372.         end
  9373.     end
  9374.  
  9375.     -- Generate a job GUID for remote agents. This will be used by the UI to uniquely
  9376.     -- identify rows returned by the enums
  9377.     if @local_job = 0
  9378.     begin
  9379.         set @job_id = newid();
  9380.     end
  9381.  
  9382.     UPDATE MSlogreader_agents SET name = @name,
  9383.         job_id = @job_id WHERE
  9384.         id = @agent_id
  9385.     IF @@ERROR <> 0
  9386.         GOTO UNDO
  9387.  
  9388.     -- Update global replication status table
  9389.     EXEC dbo.sp_MSupdate_replication_status
  9390.         @publisher,
  9391.         @publisher_db,
  9392.         @publication,
  9393.         @agent_type = 2,
  9394.         @agent_name = @name,
  9395.         @status = 0     -- not running status
  9396.  
  9397.  
  9398.     COMMIT TRAN
  9399.  
  9400.     RETURN(0)
  9401.  
  9402. UNDO:
  9403.     if @@TRANCOUNT = 1
  9404.         ROLLBACK TRAN
  9405.     else
  9406.         COMMIT TRAN
  9407.     return(1)
  9408. GO
  9409.  
  9410. raiserror(15339,-1,-1,'sp_MSadd_publication')
  9411. go
  9412. CREATE PROCEDURE sp_MSadd_publication
  9413. @publisher sysname,
  9414. @publisher_db sysname,
  9415. @publication sysname,
  9416. @publication_id int = 0,                    -- BUG REMOVE
  9417. @publication_type int = 1,                  -- 0 = Transactional 1 = Snapshot  2 = Merge
  9418. @independent_agent bit = 0,
  9419. @immediate_sync bit = 0,
  9420. @allow_push bit = 1,
  9421. @allow_pull bit = 0,
  9422. @allow_anonymous bit = 0,
  9423. @snapshot_agent nvarchar(100) = NULL,
  9424. @logreader_agent nvarchar (100) = NULL,
  9425. @description nvarchar(255) = NULL,
  9426. @retention int =60,
  9427. @vendor_name nvarchar(100) = 'Microsoft SQL Server'
  9428. as
  9429.  
  9430.     set nocount on
  9431.  
  9432.     declare @thirdparty_flag bit                    -- 0 = SQL Server 1 = Third Party
  9433.     declare @publisher_id smallint
  9434.     declare @retcode int
  9435.     declare @platform_nt binary
  9436.     declare @platform_desktop int
  9437.     declare @agentname nvarchar(100)
  9438.     declare @max_distretention int
  9439.  
  9440.     select @platform_nt = 0x1
  9441.     select @platform_desktop = 0x100
  9442.  
  9443.     -- Check if publisher is a defined as a distribution publisher in the current database
  9444.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  9445.     if @retcode <> 0
  9446.     begin
  9447.         return(1)
  9448.     end
  9449.  
  9450.     EXEC @retcode = sp_helpdistributor @max_distretention = @max_distretention OUTPUT
  9451.     if @retcode <>0
  9452.     begin
  9453.         return (1)
  9454.     end
  9455.  
  9456.     -- Get third party flag
  9457.     select @thirdparty_flag = thirdparty_flag from msdb..MSdistpublishers
  9458.         where UPPER(name) = UPPER(@publisher)
  9459.     
  9460.     -- Parameter Check: @publication_type
  9461.     -- Make sure that the publication type is one of the following:
  9462.     -- 0  transactional
  9463.     -- 1  snapshot
  9464.     -- 2  merge
  9465.     if @publication_type not in (0,1,2)
  9466.     begin
  9467.         raiserror(20033, 16, -1)
  9468.         return (1)
  9469.     end
  9470.  
  9471.     -- disable tran publishing on Win9x and/or desktop sku
  9472.     if (@publication_type = 0) and (platform() & @platform_nt != @platform_nt)
  9473.     begin
  9474.         raiserror(21052, 16, -1)
  9475.         return (1)
  9476.     end
  9477.  
  9478.     if (@publication_type = 0) and (platform() & @platform_desktop = @platform_desktop)
  9479.     begin
  9480.         raiserror(21108, 16, -1)
  9481.         return (1)
  9482.     end
  9483.  
  9484.     -- Parameter Check: @immediate_sync
  9485.     -- The publication must support independent_agent to support immediate_sync
  9486.     if @immediate_sync = 1 and @independent_agent != 1
  9487.     begin
  9488.         raiserror(21022, 16, -1)
  9489.         return (1)
  9490.     end
  9491.  
  9492.     -- Parameter Check: @allow_anonymous
  9493.     -- The publication must support immediate_sync to support anonymous.
  9494.     if @allow_anonymous = 1 and @immediate_sync != 1
  9495.     begin
  9496.         raiserror(20011, 16, -1)
  9497.         return (1)
  9498.     end
  9499.     
  9500.     -- Make sure publication does not already exist
  9501.     if exists (select * from MSpublications where publication = @publication and
  9502.         publisher_id = @publisher_id and publisher_db = @publisher_db)
  9503.     begin
  9504.         if @thirdparty_flag = 1
  9505.         begin
  9506.             raiserror(14016, 16, -1, @publication)
  9507.             return (1)
  9508.         end
  9509.         else
  9510.         begin
  9511.             exec @retcode = dbo.sp_MSdrop_publication 
  9512.                 @publisher = @publisher,
  9513.                 @publisher_db = @publisher_db,
  9514.                 @publication = @publication
  9515.             if @@error <> 0 or @retcode <> 0
  9516.                 return (1)
  9517.         end
  9518.     end
  9519.  
  9520.     begin tran
  9521.     save tran MSadd_publication
  9522.  
  9523.     insert into MSpublications values (@publisher_id, @publisher_db, @publication, 
  9524.         @publication_type, @thirdparty_flag, @independent_agent, @immediate_sync, @allow_push,
  9525.         @allow_pull, @allow_anonymous, @description, @vendor_name, @retention)
  9526.     if @@error <> 0
  9527.         goto UNDO
  9528.  
  9529.     -- Enable the distribution cleanup agent if transactional or snapshot publicational
  9530.     if @publication_type = 0 or @publication_type = 1
  9531.     begin
  9532.         select @agentname = name from msdb..sysjobs j, msdb..sysjobsteps s where 
  9533.             j.job_id = s.job_id and
  9534.             j.category_id = 11 and
  9535.             s.database_name = db_name()
  9536.  
  9537.         exec @retcode = msdb.dbo.sp_update_job @job_name=@agentname, @enabled=1
  9538.         if @@error <> 0 or @retcode <> 0
  9539.             goto UNDO
  9540.     end
  9541.  
  9542.     -- Add snapshot and logreader agent
  9543.     -- If null is passed in, we know that the agent is created already. (For SQL server).
  9544.     -- If not null is passed in, add the agents without creating local jobs (For third party).
  9545.  
  9546.     if @snapshot_agent is not null
  9547.     begin
  9548.         exec @retcode = dbo.sp_MSadd_snapshot_agent
  9549.             @name = @snapshot_agent,
  9550.             @publisher = @publisher,
  9551.             @publisher_db = @publisher_db,
  9552.             @publication = @publication,
  9553.             @publication_type = @publication_type,
  9554.             @local_job = 0
  9555.         if @@error <> 0 or @retcode <> 0
  9556.             goto UNDO
  9557.     end
  9558.  
  9559.     if @logreader_agent is not null
  9560.     begin
  9561.         exec @retcode = dbo.sp_MSadd_logreader_agent
  9562.             @name = @logreader_agent,
  9563.             @publisher = @publisher,
  9564.             @publisher_db = @publisher_db,
  9565.             @publication = @publication,
  9566.             @local_job = 0
  9567.         if @@error <> 0 or @retcode <> 0
  9568.             goto UNDO
  9569.     end
  9570.  
  9571.     -- If publisher_id, publisher_db pair is not in MSpublisher_databases then add it.  This will be used
  9572.     -- to store a publisher_database_id in the MSrepl_transactions and MSrepl_commands table.
  9573.     if not exists (select * from MSpublisher_databases where publisher_id = @publisher_id and
  9574.         publisher_db = @publisher_db)
  9575.     begin
  9576.         insert into MSpublisher_databases (publisher_id, publisher_db) values (@publisher_id, @publisher_db)
  9577.         if @@error <> 0
  9578.             goto UNDO
  9579.     end
  9580.  
  9581.     commit tran
  9582.  
  9583.     return(0)
  9584.  
  9585. UNDO:
  9586.     if @@TRANCOUNT > 0
  9587.     begin
  9588.         ROLLBACK TRAN MSadd_publication
  9589.         COMMIT TRAN
  9590.     end
  9591.     return(1)
  9592. GO
  9593.  
  9594. /* 
  9595. **  History runstatus values defined in sqlrepl.h
  9596. **
  9597. **  Start       1
  9598. **  Succeed     2
  9599. **  Inprogress  3
  9600. **  Idle        4
  9601. **  Retry       5
  9602. **  Failure     6
  9603. */
  9604. GO
  9605.  
  9606. raiserror(15339,-1,-1,'sp_MSrepl_raiserror')
  9607. go
  9608. create proc sp_MSrepl_raiserror
  9609. @agent sysname,
  9610. @agent_name nvarchar(100),
  9611. @status int,
  9612. @message nvarchar(255),
  9613. @subscriber sysname = NULL,
  9614. @publication sysname = NULL,
  9615. @article sysname = NULL
  9616. as
  9617.     if @status = 2      --Succeeded
  9618.         raiserror (14150, 10, -1, @agent, @agent_name, @message)
  9619.     else if @status = 5 --Retry Failure
  9620.         raiserror (14152, 10, -1, @agent, @agent_name, @message)
  9621.     else if @status = 6 --Failure
  9622.     begin
  9623.         raiserror (14151, 18, -1, @agent, @agent_name, @message)
  9624.     end
  9625.     else if @status = 7
  9626.     begin
  9627.         raiserror (20574, 10, -1, @subscriber, @article, @publication)
  9628.     end
  9629.     else if @status = 8
  9630.     begin
  9631.         raiserror (20575, 10, -1, @subscriber, @article, @publication)
  9632.     end
  9633.     else if @status = 9
  9634.     begin
  9635.         raiserror (14158, 10, -1, @agent, @agent_name, @message)
  9636.     end
  9637.  
  9638. go
  9639.  
  9640. raiserror(15339,-1,-1,'sp_MSget_new_errorid')
  9641. GO
  9642.  
  9643. CREATE PROCEDURE sp_MSget_new_errorid
  9644. @errorid int OUTPUT 
  9645. AS
  9646.     set nocount on
  9647.  
  9648.     SELECT @errorid = NULL
  9649.  
  9650.     BEGIN TRAN sp_MSget_new_errorid
  9651.  
  9652.     SET ROWCOUNT 1
  9653.     SELECT @errorid = id FROM MSrepl_errors (UPDLOCK PAGLOCK)
  9654.         ORDER BY id DESC
  9655.     SET ROWCOUNT 0
  9656.  
  9657.     IF @errorid IS NULL
  9658.         SELECT @errorid = 1
  9659.     ELSE
  9660.         SELECT @errorid = @errorid + 1
  9661.  
  9662.     INSERT INTO MSrepl_errors VALUES (@errorid, 
  9663.         GETDATE(), NULL, /* Error with type NULL is placeholder, refer to sp_MSget_repl_error */
  9664.         NULL, NULL, NULL, NULL)
  9665.  
  9666.     /* return an 0 error_id if failed to insert the row */
  9667.     IF @@ERROR <> 0
  9668.         SELECT @errorid = 0
  9669.  
  9670.     SELECT @errorid
  9671.  
  9672.     COMMIT TRAN
  9673. GO   
  9674.  
  9675. raiserror(15339,-1,-1,'sp_MSadd_snapshot_history')
  9676. go
  9677. CREATE PROCEDURE sp_MSadd_snapshot_history
  9678. @agent_id int,
  9679. @runstatus int, 
  9680. @comments nvarchar(255),
  9681. @delivered_transactions int = 0,    
  9682. @delivered_commands int = 0,        
  9683. @log_error bit = 0,
  9684. @perfmon_increment bit = 1,
  9685. @update_existing_row bit = 0,
  9686. @do_raiserror bit = 1
  9687. AS
  9688.  
  9689.     DECLARE @current_time datetime
  9690.     DECLARE @start_time datetime
  9691.     DECLARE @duration int
  9692.     DECLARE @delivery_rate float
  9693.     DECLARE @error_id int
  9694.     DECLARE @retcode int
  9695.     DECLARE @idle int
  9696.     DECLARE @succeed int
  9697.     DECLARE @startup int
  9698.     DECLARE @retry int
  9699.     DECLARE @failure int
  9700.     DECLARE @inprogress int
  9701.     DECLARE @lastrow_timestamp timestamp
  9702.     DECLARE @publisher sysname
  9703.     DECLARE @publisher_db sysname
  9704.     DECLARE @publication sysname
  9705.     DECLARE @agent_name nvarchar(100)
  9706.     DECLARE @perfmon_delivery_rate int
  9707.  
  9708.     /* 
  9709.     ** Status const defined in sqlrepl.h 
  9710.     */
  9711.     set @startup = 1
  9712.     set @succeed = 2
  9713.     set @inprogress = 3
  9714.     set @idle = 4
  9715.     set @retry = 5
  9716.     set @failure = 6
  9717.  
  9718.  
  9719.     SELECT @current_time = GETDATE()
  9720.  
  9721.     -- Get named information 
  9722.     select @publisher = srvname, @publisher_db = publisher_db, @publication = publication,
  9723.         @agent_name = name from master..sysservers, MSsnapshot_agents where
  9724.         id = @agent_id and
  9725.         publisher_id = srvid
  9726.  
  9727.     -- Update Perfmon counter
  9728.     if @perfmon_increment = 1
  9729.     begin
  9730.         if @runstatus = @startup
  9731.             dbcc incrementinstance ("SQL Replication Agents", "Running", "Snapshot", 1)
  9732.         else if (@runstatus = @succeed or @runstatus = @retry or @runstatus = @failure)
  9733.             dbcc incrementinstance ("SQL Replication Agents", "Running", "Snapshot", -1)
  9734.     end
  9735.  
  9736.     /* Get start_time for latest agent run */
  9737.     IF @runstatus <> 1  -- Start status
  9738.     BEGIN
  9739.         SELECT TOP 1 @start_time = start_time, @lastrow_timestamp = timestamp
  9740.             FROM MSsnapshot_history (rowlock)
  9741.             WHERE 
  9742.             agent_id = @agent_id
  9743.             ORDER BY timestamp DESC
  9744.     END
  9745.     ELSE
  9746.         SELECT @start_time = @current_time
  9747.  
  9748.     /* Calculate agent run duration */
  9749.     SELECT @duration = DATEDIFF(second, @start_time, @current_time) 
  9750.  
  9751.     /* Calculate delivery_rate */
  9752.     IF @duration <> 0 
  9753.        SELECT @delivery_rate = (@delivered_commands * 1.0)/@duration 
  9754.     ELSE
  9755.        SELECT @delivery_rate = 0
  9756.  
  9757.     -- Set Perfmon counters
  9758.     if @runstatus = @idle or @runstatus = @inprogress
  9759.     begin
  9760.         dbcc addinstance ("SQL Replication Snapshot", @agent_name)
  9761.         dbcc incrementinstance ("SQL Replication Snapshot", "Snapshot:Delivered Cmds/sec", @agent_name, @delivered_commands)
  9762.         dbcc incrementinstance ("SQL Replication Snapshot", "Snapshot:Delivered Trans/sec", @agent_name, @delivered_transactions)
  9763.     end
  9764.  
  9765.     /* 
  9766.     ** Set error id to 0 unless the user want to log errors associate with this 
  9767.     ** history message.
  9768.     */
  9769.     SELECT @error_id = 0
  9770.     IF @log_error = 1
  9771.         -- Ignore errors here. @error_id will be set to 0 in case of errors  
  9772.         EXEC dbo.sp_MSget_new_errorid @error_id OUTPUT
  9773.  
  9774.     -- Insert idle record or update if history record is already 'idle'
  9775.     IF @runstatus = @idle or @update_existing_row = 1
  9776.     begin
  9777.         -- Attempt to update the last row if it is IDLE
  9778.         UPDATE MSsnapshot_history SET runstatus = @runstatus, time = @current_time, duration = @duration,
  9779.             comments = @comments,
  9780.             delivered_transactions = @delivered_transactions,
  9781.             delivered_commands = @delivered_commands,
  9782.             delivery_rate = @delivery_rate
  9783.             WHERE
  9784.             agent_id = @agent_id and
  9785.             timestamp = @lastrow_timestamp and
  9786.             runstatus = @runstatus
  9787.  
  9788.         -- Insert idle record if there is not one
  9789.         if @@ROWCOUNT = 0
  9790.         begin
  9791.             INSERT INTO MSsnapshot_history VALUES (@agent_id, @runstatus, @start_time, 
  9792.             @current_time, @duration, @comments, @delivered_transactions, @delivered_commands, 
  9793.             @delivery_rate, @error_id, NULL)
  9794.         end
  9795.     end
  9796.     else
  9797.     begin
  9798.         INSERT INTO MSsnapshot_history VALUES (@agent_id, @runstatus, @start_time, 
  9799.             @current_time, @duration, @comments, @delivered_transactions, @delivered_commands, 
  9800.             @delivery_rate, @error_id, NULL)
  9801.     end
  9802.  
  9803.     -- Update global replication agent status table
  9804.     exec dbo.sp_MSupdate_replication_status 
  9805.         @publisher, 
  9806.         @publisher_db,
  9807.         @publication,
  9808.         @agent_type = 1,
  9809.         @agent_name = @agent_name,
  9810.         @status = @runstatus
  9811.  
  9812.     -- Raise the appropriate error
  9813.     if @do_raiserror = 1
  9814.         exec dbo.sp_MSrepl_raiserror 'Snapshot', @agent_name, @runstatus, @comments
  9815.  
  9816.     IF @@ERROR <> 0
  9817.        RETURN (1)
  9818. GO   
  9819.  
  9820.  
  9821. raiserror(15339,-1,-1,'sp_MSadd_logreader_history')
  9822. go
  9823. CREATE PROCEDURE sp_MSadd_logreader_history
  9824. @agent_id int,
  9825. @runstatus int,
  9826. @comments nvarchar(255),
  9827. @xact_seqno varbinary(16) = NULL,
  9828. @delivery_time int = 0,                 -- Current delivery time (milliseconds)
  9829. @delivered_transactions int = 0,        -- Running total of session
  9830. @delivered_commands int = 0,            -- Running total of session
  9831. @delivery_latency int = 0,              -- Current latency 
  9832. @log_error bit = 0,
  9833. @perfmon_increment bit = 1,
  9834. @update_existing_row bit = 0,
  9835. @do_raiserror bit = 1
  9836. AS
  9837.  
  9838.     DECLARE @current_time datetime
  9839.     DECLARE @start_time datetime
  9840.     DECLARE @duration int
  9841.     DECLARE @average_commands int
  9842.     DECLARE @delivery_rate float
  9843.     DECLARE @error_id int
  9844.     DECLARE @retcode int
  9845.     DECLARE @idle int
  9846.     DECLARE @succeed int
  9847.     DECLARE @startup int
  9848.     DECLARE @retry int
  9849.     DECLARE @inprogress int
  9850.     DECLARE @failure int
  9851.     DECLARE @lastrow_timestamp timestamp
  9852.     DECLARE @publisher sysname
  9853.     DECLARE @publisher_db sysname
  9854.     DECLARE @publication sysname
  9855.     DECLARE @agent_name nvarchar(100)
  9856.     DECLARE @last_delivered_commands int
  9857.     DECLARE @last_delivered_transactions int
  9858.     DECLARE @latest_delivered_commands int
  9859.     DECLARE @latest_delivered_transactions int
  9860.     DECLARE @latest_delivery_rate int
  9861.     DECLARE @last_delivery_rate int             -- int for perfmon
  9862.     DECLARE @last_delivery_latency int
  9863.     DECLARE @last_delivery_time int
  9864.     DECLARE @avg_delivery_rate float
  9865.     DECLARE @avg_delivery_latency int
  9866.     DECLARE @total_delivery_time int
  9867.  
  9868.     /* 
  9869.     ** Status const defined in sqlrepl.h 
  9870.     */
  9871.     set @startup = 1
  9872.     set @succeed = 2
  9873.     set @inprogress = 3
  9874.     set @idle = 4
  9875.     set @retry = 5
  9876.     set @failure = 6
  9877.  
  9878.     SELECT @current_time = GETDATE()
  9879.  
  9880.     -- Update Perfmon counter
  9881.     if @perfmon_increment = 1
  9882.     begin
  9883.         if @runstatus = @startup
  9884.             dbcc incrementinstance ("SQL Replication Agents", "Running", "Logreader", 1)
  9885.         else if (@runstatus = @succeed or @runstatus = @retry or @runstatus = @failure)
  9886.             dbcc incrementinstance ("SQL Replication Agents", "Running", "Logreader", -1)
  9887.     end
  9888.  
  9889.     /* Get start_time for latest agent run */
  9890.     IF @runstatus <> 1  -- Startup status
  9891.     BEGIN
  9892.         SELECT TOP 1 @start_time = start_time, 
  9893.             @lastrow_timestamp = timestamp, 
  9894.             @last_delivered_commands = isnull(delivered_commands, 0),
  9895.             @last_delivered_transactions = isnull(delivered_transactions, 0),
  9896.             @last_delivery_latency = isnull(delivery_latency, 0),
  9897.             @last_delivery_time = isnull(delivery_time, 0),
  9898.             @last_delivery_rate = isnull(delivery_rate, 0)
  9899.         FROM MSlogreader_history (rowlock)
  9900.             WHERE agent_id = @agent_id
  9901.                 ORDER BY timestamp DESC
  9902.     END
  9903.     ELSE
  9904.     BEGIN
  9905.         SELECT @start_time = @current_time
  9906.         SET @last_delivered_commands = 0
  9907.         SET @last_delivered_transactions = 0
  9908.         SET @last_delivery_latency = 0
  9909.         SET @last_delivery_time = 0
  9910.         SET @last_delivery_rate = 0
  9911.         SET @last_delivery_latency = 0
  9912.     END
  9913.  
  9914.     /* Use the current time if no corresponding start_up message logged */
  9915.     IF @start_time is NULL
  9916.        SELECT @start_time = @current_time
  9917.  
  9918.     -- Calculate number of transactions in this history
  9919.     set @latest_delivered_commands = @delivered_commands - @last_delivered_commands
  9920.  
  9921.     -- Calculate number of commands in this history
  9922.     set @latest_delivered_transactions = @delivered_transactions - @last_delivered_transactions
  9923.  
  9924.     /* Calculate agent run duration */
  9925.     SELECT @duration = DATEDIFF(second, @start_time, @current_time) 
  9926.  
  9927.     -- Calculate total delivery_time 
  9928.     if @latest_delivered_commands <> 0      -- Work around for Logreader passing in @delivery_time on shutdown.
  9929.         SELECT @total_delivery_time = @delivery_time + @last_delivery_time
  9930.     else
  9931.         SELECT @total_delivery_time = @last_delivery_time
  9932.  
  9933.     -- Calculate average delivery_rate of the session
  9934.     IF @latest_delivered_commands <> 0 and @total_delivery_time <> 0
  9935.     BEGIN
  9936.         SELECT @avg_delivery_rate = (@delivered_commands * 1.0)/(@total_delivery_time/1000.0)
  9937.  
  9938.         -- Current history delivery rate
  9939.         if @delivery_time <> 0
  9940.             SELECT @latest_delivery_rate = (@latest_delivered_commands * 1.0)/(@delivery_time/1000.0)
  9941.         else 
  9942.             SELECT @latest_delivery_rate = 0
  9943.     END
  9944.     ELSE
  9945.     BEGIN
  9946.         SELECT @avg_delivery_rate = @last_delivery_rate
  9947.         SELECT @latest_delivery_rate = 0
  9948.     END
  9949.  
  9950.     -- Calculate the average delivery_latency of the session
  9951.     if @latest_delivered_commands <> 0      -- Work around for Logreader passing in @delivery_latency on shutdown.
  9952.     BEGIN
  9953.         IF @delivery_latency <> 0
  9954.             IF @last_delivery_latency <> 0
  9955.                 SELECT @avg_delivery_latency = (@delivery_latency + @last_delivery_latency)/2
  9956.             ElSE
  9957.                 SELECT @avg_delivery_latency = @delivery_latency
  9958.         ELSE
  9959.             SELECT @avg_delivery_latency = 0
  9960.     END
  9961.     ELSE
  9962.     BEGIN
  9963.         SELECT @avg_delivery_latency = @last_delivery_latency
  9964.  
  9965.         -- Ignore latency value if no commands
  9966.         SELECT @delivery_latency = 0    
  9967.     END
  9968.  
  9969.     /*
  9970.     ** Calculate average number of commands per transaction
  9971.     */
  9972.     IF @delivered_commands <> 0
  9973.        SELECT @average_commands = @delivered_commands/@delivered_transactions
  9974.     ELSE
  9975.  
  9976.        SELECT @average_commands = 0
  9977.  
  9978.     -- Set Perfmon counters
  9979.     select @agent_name = name from MSlogreader_agents where id = @agent_id
  9980.     if @runstatus = @idle or @runstatus = @inprogress
  9981.     begin
  9982.         dbcc addinstance ("SQL Replication Logreader", @agent_name)
  9983.         dbcc incrementinstance ("SQL Replication Logreader", "Logreader:Delivered Trans/sec", @agent_name, @latest_delivered_transactions)
  9984.         dbcc incrementinstance ("SQL Replication Logreader", "Logreader:Delivered Cmds/sec", @agent_name, @latest_delivered_commands)
  9985.         dbcc setinstance ("SQL Replication Logreader", "Logreader:Delivery Latency", @agent_name, @delivery_latency)
  9986.     end
  9987.     else
  9988.     begin
  9989.         dbcc addinstance ("SQL Replication Logreader", @agent_name)
  9990.         dbcc setinstance ("SQL Replication Logreader", "Logreader:Delivery Latency", @agent_name, 0)
  9991.     end
  9992.  
  9993.     /* 
  9994.     ** Set error id to 0 unless the user want to log errors associate with this 
  9995.     ** history message.
  9996.     */
  9997.     SELECT @error_id = 0
  9998.     IF @log_error = 1
  9999.         -- Ignore errors here. @error_id will be set to 0 in case of errors  
  10000.         EXEC dbo.sp_MSget_new_errorid @error_id OUTPUT
  10001.  
  10002.     -- Insert idle record or update if history record is already 'idle'
  10003.     IF @runstatus = @idle or @update_existing_row = 1
  10004.     begin
  10005.         -- Attempt to update the last row if it is IDLE
  10006.         if (@runstatus = @idle)
  10007.         begin
  10008.             UPDATE MSlogreader_history SET runstatus = @runstatus, time = @current_time,
  10009.             duration = @duration,comments = @comments
  10010.             WHERE
  10011.             agent_id = @agent_id and
  10012.             timestamp = @lastrow_timestamp and
  10013.             ( runstatus = @runstatus or 
  10014.             (@update_existing_row = 1 and runstatus in (@idle, @inprogress) and @runstatus in (@idle, @inprogress)) )
  10015.         end
  10016.         else
  10017.         begin
  10018.             UPDATE MSlogreader_history SET runstatus = @runstatus, start_time = @start_time, 
  10019.             time = @current_time,
  10020.             duration = @duration, comments = @comments,
  10021.             xact_seqno = @xact_seqno,
  10022.             delivery_time = @total_delivery_time,
  10023.             delivered_transactions = @delivered_transactions,
  10024.             delivered_commands = @delivered_commands,
  10025.             average_commands = @average_commands,
  10026.             delivery_rate = @avg_delivery_rate,
  10027.             delivery_latency = @avg_delivery_latency,
  10028.             error_id = @error_id
  10029.             WHERE
  10030.             agent_id = @agent_id and
  10031.             timestamp = @lastrow_timestamp and
  10032.             ( runstatus = @runstatus or 
  10033.             (@update_existing_row = 1 and runstatus in (@idle, @inprogress) and @runstatus in (@idle, @inprogress)) )
  10034.         end
  10035.  
  10036.         -- Insert idle record if there is not one
  10037.         if @@ROWCOUNT = 0
  10038.         begin
  10039.             -- Use last values because nothing was done
  10040.             INSERT INTO MSlogreader_history VALUES (@agent_id, @runstatus, @start_time, @current_time, 
  10041.                 @duration, @comments,  
  10042.                 @xact_seqno, @last_delivery_time, @delivered_transactions, @delivered_commands,
  10043.                 @average_commands, @avg_delivery_rate, @last_delivery_latency, @error_id, NULL)
  10044.         end
  10045.     end
  10046.     else
  10047.     begin
  10048.         INSERT INTO MSlogreader_history VALUES (@agent_id, @runstatus, @start_time, @current_time, 
  10049.             @duration, @comments, 
  10050.             @xact_seqno, @total_delivery_time, @delivered_transactions, @delivered_commands,
  10051.             @average_commands, @avg_delivery_rate, @avg_delivery_latency, @error_id, NULL)
  10052.     end
  10053.  
  10054.     -- Get named information 
  10055.     select @publisher = srvname, @publisher_db = publisher_db, @publication = publication,
  10056.         @agent_name = name from master..sysservers, MSlogreader_agents where
  10057.         id = @agent_id and
  10058.         publisher_id = srvid
  10059.  
  10060.     -- Update global replication agent status table
  10061.     exec dbo.sp_MSupdate_replication_status 
  10062.         @publisher, 
  10063.         @publisher_db,
  10064.         @publication = 'ALL',
  10065.         @agent_type = 2,
  10066.         @agent_name = @agent_name,
  10067.         @status = @runstatus
  10068.  
  10069.     -- Raise the appropriate error
  10070.     if @do_raiserror = 1
  10071.         exec dbo.sp_MSrepl_raiserror 'LogReader', @agent_name, @runstatus, @comments
  10072.  
  10073.     IF @@ERROR <> 0
  10074.     BEGIN
  10075.        RETURN (1)
  10076.     END
  10077.  
  10078. GO      
  10079.  
  10080. raiserror(15339,-1,-1,'sp_MSadd_distribution_history')
  10081. go
  10082. CREATE PROCEDURE sp_MSadd_distribution_history
  10083. @agent_id int,
  10084. @runstatus int, 
  10085. @comments nvarchar(255),
  10086. @xact_seqno binary(16) = 0x00,      -- We use binary(16)to pad it out for the below compare
  10087. @delivered_transactions int = 0,        -- Running total for the session
  10088. @delivered_commands int = 0,            -- Running total for the session
  10089. @delivery_rate float = 0,               -- Last rate (cmds/sec)
  10090. @log_error bit = 0,
  10091. @perfmon_increment bit = 1,
  10092. @xactseq varbinary(16) = NULL,      
  10093. @command_id int = NULL,
  10094. @update_existing_row bit = 0,
  10095. @updateable_row bit = 1,        -- used to override history verbose level to decide
  10096.                             -- whether the row being added can be updated by another.    
  10097. @do_raiserror bit = 1
  10098. AS
  10099.  
  10100.     set nocount on
  10101.  
  10102.     DECLARE @current_time datetime
  10103.     DECLARE @start_time datetime
  10104.     DECLARE @entry_time datetime
  10105.     DECLARE @duration int                   -- milliseconds
  10106.     DECLARE @delivery_latency int
  10107.     DECLARE @average_commands int
  10108.     DECLARE @total_cmds int
  10109.     DECLARE @publisher_id smallint
  10110.     DECLARE @publisher_db sysname
  10111.     DECLARE @publication sysname
  10112.     DECLARE @publisher sysname
  10113.     DECLARE @subscriber_id smallint
  10114.     DECLARE @subscriber sysname
  10115.     DECLARE @subscriber_db sysname
  10116.     DECLARE @article sysname
  10117.     DECLARE @article_id int
  10118.     DECLARE @publication_id int
  10119.     DECLARE @publisher_database_id int
  10120.  
  10121.     DECLARE @agent_name nvarchar(100)
  10122.     DEClARE @error_id int 
  10123.     DECLARE @startup int
  10124.     DECLARE @succeed int
  10125.     DECLARE @inprogress int
  10126.     DECLARE @retry int
  10127.     DECLARE @failure int
  10128.     DECLARE @validation_failure int
  10129.     DECLARE @validation_success int
  10130.     DECLARE @requested_shutdown int
  10131.     DECLARE @raiserror_status int
  10132.     DECLARE @idle int
  10133.     DECLARE @lastrow_timestamp timestamp
  10134.     declare @lastrow_xact_seqno binary(16)
  10135.     DECLARE @new_delivered_commands int
  10136.     DECLARE @new_delivered_transactions int
  10137.     DECLARE @retcode int
  10138.     DECLARE @last_delivery_rate float
  10139.     DECLARE @last_delivery_latency int
  10140.     DECLARE @avg_delivery_rate float
  10141.     DECLARE @avg_delivery_latency int
  10142.     DECLARE @perfmon_delivery_rate int
  10143.     DECLARE @existing_row_updateble bit
  10144.     DECLARE @this_row_updateable bit
  10145.  
  10146.     /* 
  10147.     ** Status const defined in sqlrepl.h 
  10148.     */
  10149.     set @startup = 1
  10150.     set @succeed = 2
  10151.     set @inprogress = 3
  10152.     set @idle = 4
  10153.     set @retry = 5
  10154.     set @failure = 6
  10155.     set @validation_failure = 7
  10156.     set @validation_success = 8
  10157.     set @requested_shutdown = 9
  10158.  
  10159.     -- To prevent cleanup up being messed up by invalid history message, only log
  10160.     -- valid history message. 
  10161.     if @runstatus > 9 or @runstatus < 1
  10162.     begin
  10163.         --Invalid history message logged
  10164.         RAISERROR (21079, 16, -1, @runstatus)
  10165.         return (1)
  10166.     end
  10167.  
  10168.     select @existing_row_updateble = 1
  10169.     select @this_row_updateable = 1
  10170.  
  10171.     select @raiserror_status = @runstatus
  10172.     if (@runstatus = @validation_failure or @runstatus = @validation_success or @runstatus = @requested_shutdown)
  10173.     begin
  10174.         select @runstatus = @inprogress
  10175.         select @this_row_updateable = 0
  10176.     end
  10177.  
  10178.     if (@updateable_row = 0)
  10179.     begin
  10180.         select @this_row_updateable = 0
  10181.     end
  10182.     
  10183.     -- Security Check
  10184.     exec @retcode = dbo.sp_MScheck_pull_access
  10185.         @agent_id = @agent_id,
  10186.         @agent_type = 0 -- distribution agent
  10187.     if @@error <> 0 or @retcode <> 0
  10188.         return (1)
  10189.  
  10190.     SELECT @current_time = GETDATE()
  10191.  
  10192.     -- Update Perfmon counter
  10193.     if @perfmon_increment = 1
  10194.     begin
  10195.         if @runstatus = @startup
  10196.             dbcc incrementinstance ("SQL Replication Agents", "Running", "Distribution", 1)
  10197.         else if (@runstatus = @succeed or @runstatus = @retry or @runstatus = @failure)
  10198.             dbcc incrementinstance ("SQL Replication Agents", "Running", "Distribution", -1)
  10199.     end
  10200.  
  10201.     -- Get agent name, publisher id and publisher_db
  10202.     select @agent_name = name, 
  10203.         @publisher_database_id = publisher_database_id,
  10204.         @publisher_id = publisher_id, @publisher_db = publisher_db,
  10205.         @publication =  publication, @subscriber_id = subscriber_id, @subscriber_db = subscriber_db
  10206.         from MSdistribution_agents
  10207.         where id = @agent_id
  10208.     select @publisher = srvname from master..sysservers where srvid = @publisher_id
  10209.     select @subscriber = srvname from master..sysservers where srvid = @subscriber_id
  10210.  
  10211.     /* Get start_time and xact_seqno for latest agent run */
  10212.     IF @runstatus <> 1   
  10213.     BEGIN
  10214.           
  10215.         SELECT TOP 1 
  10216.             @lastrow_xact_seqno = xact_seqno,
  10217.             @start_time = start_time, 
  10218.             @total_cmds = total_delivered_commands,
  10219.             @lastrow_timestamp = timestamp, 
  10220.             @new_delivered_transactions = @delivered_transactions - delivered_transactions,
  10221.             @new_delivered_commands = @delivered_commands - delivered_commands,
  10222.             @last_delivery_rate = delivery_rate,
  10223.             @last_delivery_latency = delivery_latency,
  10224.             @existing_row_updateble = updateable_row
  10225.         FROM MSdistribution_history (rowlock)
  10226.             WHERE agent_id = @agent_id 
  10227.             ORDER BY timestamp  DESC
  10228.     END
  10229.     ELSE
  10230.     BEGIN
  10231.         -- At least get running total of commands over all sessions.
  10232.         SELECT TOP 1 
  10233.             @lastrow_xact_seqno = xact_seqno,
  10234.             @total_cmds = total_delivered_commands
  10235.             FROM MSdistribution_history  (rowlock)
  10236.             WHERE agent_id = @agent_id
  10237.             ORDER BY timestamp  DESC
  10238.         SELECT @start_time = @current_time
  10239.         SELECT @new_delivered_commands = @delivered_commands
  10240.         SELECT @new_delivered_transactions = @delivered_transactions
  10241.         SELECT @last_delivery_rate = 0
  10242.         SELECT @last_delivery_latency = 0
  10243.     END
  10244.  
  10245.     IF @total_cmds IS NULL
  10246.         SELECT @total_cmds = 0
  10247.  
  10248.     /* Use the current time if no corresponding start_up message logged */
  10249.     IF @start_time is NULL
  10250.        SELECT @start_time = @current_time
  10251.  
  10252.     /* Calculate agent run duration */
  10253.     SELECT @duration = DATEDIFF(second, @start_time, @current_time) 
  10254.     
  10255.     IF @delivered_commands <> 0
  10256.        SELECT @average_commands = @delivered_commands/@delivered_transactions
  10257.     ELSE
  10258.        SELECT @average_commands = 0
  10259.  
  10260.     -- Get the entry time of the last distributed transaction
  10261.     if @xact_seqno <> 0x00 and @new_delivered_commands <> 0
  10262.         -- SELECT @entry_time = entry_time FROM MSrepl_transactions (READPAST)
  10263.         SELECT @entry_time = entry_time FROM MSrepl_transactions 
  10264.            WHERE xact_seqno = @xact_seqno and
  10265.                 publisher_database_id = @publisher_database_id
  10266.  
  10267.     -- Calculate the latency of the last distributed transaction
  10268.     IF @entry_time IS NOT NULL
  10269.      begin
  10270.         -- Calculte diff in minutes.
  10271.         declare @diff_min int
  10272.         select @diff_min = DATEDIFF(minute, @entry_time, @current_time)
  10273.         if @diff_min > 16666
  10274.              select @delivery_latency = 999999999
  10275.        else 
  10276.              select @delivery_latency = DATEDIFF(millisecond, @entry_time, @current_time)
  10277.      end
  10278.     ELSE
  10279.        SELECT @delivery_latency = 0
  10280.  
  10281.     -- Calculate the average delivery latency of the session
  10282.     IF @last_delivery_latency = 0
  10283.         SET @avg_delivery_latency = @delivery_latency
  10284.     ELSE IF @delivery_latency = 0
  10285.         SET @avg_delivery_latency = @last_delivery_latency
  10286.     ELSE
  10287.         SET @avg_delivery_latency = (@delivery_latency + @last_delivery_latency)/2
  10288.  
  10289.     -- Calculate average delivery rate of the session
  10290.  
  10291.     IF @last_delivery_rate = 0
  10292.         SET @avg_delivery_rate = @delivery_rate
  10293.     ELSE IF @delivery_rate = 0 or @new_delivered_commands = 0
  10294.         SET @avg_delivery_rate = @last_delivery_rate
  10295.     ELSE
  10296.         SET @avg_delivery_rate = (@delivery_rate + @last_delivery_rate)/2.0     
  10297.  
  10298.     /* Calculate grand total of delivered trans across sessions */
  10299.     SELECT @total_cmds = @total_cmds + @new_delivered_commands
  10300.  
  10301.     -- Set Perfmon counters
  10302.     if @runstatus = @idle or @runstatus = @inprogress
  10303.     begin
  10304.         dbcc addinstance ("SQL Replication Distribution", @agent_name)
  10305.         dbcc incrementinstance ("SQL Replication Distribution", "Dist:Delivered Trans/sec", @agent_name, @new_delivered_transactions)
  10306.         dbcc incrementinstance ("SQL Replication Distribution", "Dist:Delivered Cmds/sec", @agent_name, @new_delivered_commands)
  10307.         dbcc setinstance ("SQL Replication Distribution", "Dist:Delivery Latency", @agent_name, @delivery_latency)
  10308.     end
  10309.     else
  10310.     begin /* Reset latency counter */
  10311.         dbcc addinstance ("SQL Replication Distribution", @agent_name)
  10312.         dbcc setinstance ("SQL Replication Distribution", "Dist:Delivery Latency", @agent_name, 0)
  10313.     end
  10314.  
  10315.     /* 
  10316.     ** Set error id to 0 unless the user want to log errors associate with this 
  10317.     ** history message.
  10318.     */
  10319.     SELECT @error_id = 0
  10320.     IF @log_error = 1
  10321.         -- Ignore errors here. @error_id will be set to 0 in case of errors  
  10322.         EXEC dbo.sp_MSget_new_errorid @error_id OUTPUT
  10323.     
  10324.     -- @xact_seqno may be uninitialized for the first several messages after
  10325.     -- the start-up of the distribtion agent. Get the correct value in that case. 
  10326.     -- We must do this because distribution cleanup will use the lastest xact_seqno
  10327.     -- as cleanup boundary.
  10328.     -- Note: @last_xact_seqno might be NULL
  10329.     -- Only do this if @xact_seqno is 0, since a smaller xact_seqno might be logged due
  10330.     -- to reinited sub for immediate_sync pub.
  10331.     -- This will prevent history being messed up by one gabage history entry.
  10332.     if @xact_seqno = 0x00 and @lastrow_xact_seqno is not null
  10333.         select @xact_seqno = @lastrow_xact_seqno 
  10334.  
  10335.     -- Insert idle record or update if history record is already 'idle'
  10336.     IF (@existing_row_updateble = 1) and (@runstatus = @idle or @update_existing_row = 1)
  10337.     begin
  10338.  
  10339.         -- Attempt to update the last row if it is IDLE
  10340.         if (@runstatus = @idle)
  10341.         begin
  10342.             UPDATE MSdistribution_history SET runstatus = @runstatus, time = @current_time,
  10343.             duration = @duration, comments = @comments,
  10344.             xact_seqno = @xact_seqno, updateable_row = @this_row_updateable
  10345.             WHERE
  10346.             agent_id = @agent_id and
  10347.             timestamp = @lastrow_timestamp and
  10348.             ( runstatus = @runstatus or 
  10349.             (@update_existing_row = 1 and runstatus in (@idle, @inprogress) and @runstatus in (@idle, @inprogress)) )
  10350.         end
  10351.         else
  10352.         begin
  10353.             -- Attempt to update the last row if it is IDLE
  10354.             UPDATE MSdistribution_history SET runstatus = @runstatus, start_time = @start_time,
  10355.                 time = @current_time,
  10356.                 duration = @duration,
  10357.                 xact_seqno = @xact_seqno,
  10358.                 comments = @comments,
  10359.                 delivered_transactions = @delivered_transactions,
  10360.                 delivered_commands = @delivered_commands,
  10361.                 average_commands = @average_commands,
  10362.                 delivery_rate = @avg_delivery_rate,
  10363.                 delivery_latency = @avg_delivery_latency,
  10364.                 total_delivered_commands = @total_cmds,
  10365.                 current_delivery_rate = @delivery_rate,
  10366.                 current_delivery_latency = @delivery_latency,
  10367.                 updateable_row = @this_row_updateable
  10368.                 WHERE
  10369.                 agent_id = @agent_id and
  10370.                 timestamp = @lastrow_timestamp and
  10371.                 ( runstatus = @runstatus or 
  10372.                 (@update_existing_row = 1 and runstatus in (@idle, @inprogress) and @runstatus in (@idle, @inprogress)) )
  10373.         end
  10374.     
  10375.         -- Insert idle record if there is not one
  10376.         if @@ROWCOUNT = 0
  10377.         begin
  10378.             INSERT INTO MSdistribution_history (agent_id, runstatus, start_time, time, duration, comments, xact_seqno,
  10379.                 delivered_transactions, delivered_commands, average_commands, delivery_rate, delivery_latency,
  10380.                 total_delivered_commands, error_id, timestamp, current_delivery_rate, current_delivery_latency, updateable_row)
  10381.             VALUES (@agent_id, @runstatus, @start_time, @current_time, 
  10382.                 @duration, @comments, @xact_seqno, @delivered_transactions, 
  10383.                 @delivered_commands, @average_commands, @avg_delivery_rate,
  10384.                 @avg_delivery_latency, @total_cmds, @error_id, NULL, @delivery_rate, @delivery_latency, @this_row_updateable)
  10385.         end
  10386.     end
  10387.     else
  10388.     begin
  10389.         INSERT INTO MSdistribution_history (agent_id, runstatus, start_time, time, duration, comments, xact_seqno,
  10390.                 delivered_transactions, delivered_commands, average_commands, delivery_rate, delivery_latency,
  10391.                 total_delivered_commands, error_id, timestamp, current_delivery_rate, current_delivery_latency, updateable_row)
  10392.         VALUES (@agent_id, @runstatus, @start_time, @current_time, 
  10393.             @duration, @comments, @xact_seqno, @delivered_transactions, 
  10394.             @delivered_commands, @average_commands, @avg_delivery_rate,
  10395.             @avg_delivery_latency, @total_cmds, @error_id, NULL, @delivery_rate, @delivery_latency, @this_row_updateable)
  10396.     end
  10397.  
  10398.     -- Update global replication agent status table
  10399.     exec dbo.sp_MSupdate_replication_status 
  10400.         @publisher, 
  10401.         @publisher_db,
  10402.         @publication,
  10403.         @agent_type = 3,
  10404.         @agent_name = @agent_name,
  10405.         @status = @runstatus
  10406.  
  10407.     if (@raiserror_status = @validation_failure or @raiserror_status = @validation_success)
  10408.     begin
  10409.         -- Get the "real" publication name (as opposed to 'ALL') and article name
  10410.         select @article_id = article_id from MSrepl_commands
  10411.         where publisher_database_id = @publisher_database_id
  10412.         and xact_seqno = @xactseq
  10413.         and command_id = @command_id
  10414.     
  10415.         select @publication = mp.publication, @publication_id = mp.publication_id
  10416.         from MSpublications as mp, MSsubscriptions as ms
  10417.         where mp.publisher_id = ms.publisher_id
  10418.         and mp.publisher_db = ms.publisher_db
  10419.         and mp.publication_id = ms.publication_id
  10420.         and ms.publisher_id = @publisher_id
  10421.         and ms.publisher_db = @publisher_db
  10422.         and ms.subscriber_id = @subscriber_id
  10423.         and ms.subscriber_db = @subscriber_db
  10424.         and ms.article_id = @article_id
  10425.  
  10426.         select @article = article
  10427.         from MSarticles
  10428.         where article_id = @article_id
  10429.         and publisher_id = @publisher_id
  10430.         and publisher_db = @publisher_db
  10431.         and publication_id = @publication_id
  10432.     end
  10433.  
  10434.     -- Raise the appropriate error
  10435.     if @do_raiserror = 1
  10436.         exec dbo.sp_MSrepl_raiserror 'Distribution', @agent_name, @raiserror_status, @comments, @subscriber=@subscriber, @publication=@publication, @article=@article
  10437.     
  10438.     IF @@ERROR <> 0
  10439.        RETURN (1)
  10440. GO   
  10441.  
  10442. raiserror(15339,-1,-1,'sp_MSsubscription_cleanup')
  10443. GO
  10444. CREATE PROCEDURE sp_MSsubscription_cleanup
  10445.     @cutoff_time datetime
  10446.     as
  10447.  
  10448.     declare @max_time datetime
  10449.     declare @active tinyint
  10450.     declare @inactive tinyint
  10451.     declare @subscribed tinyint
  10452.     declare @virtual_anonymous smallint
  10453.     declare @virtual smallint
  10454.     declare @agent_id int
  10455.     declare @retcode int
  10456.  
  10457.     set nocount on
  10458.  
  10459.     select @active = 2
  10460.     select @inactive = 0
  10461.     select @subscribed = 1
  10462.     select @virtual = -1
  10463.     select @virtual_anonymous = -2
  10464.  
  10465.     select @max_time = dateadd(hour, 1, getdate())
  10466.  
  10467.     -- Refer to sp_MSmaximun_cleanup_xact_seqno to understand the logic
  10468.     -- in this sp. If you change the logic here, you may need to change
  10469.     -- that sp as well.
  10470.  
  10471.     -- Deactivate real subscriptions for agents that are working on 
  10472.     -- transactions that are older than @retention
  10473.     -- update all the subscriptions for those agents, including
  10474.     -- subscriptions that are in subscribed state!
  10475.     update MSsubscriptions  set status = @inactive where
  10476.         agent_id in (
  10477.         select a.id from 
  10478.             (select s.agent_id, s.subscription_seqno, max(isnull(h.timestamp,0x00))
  10479.                 from 
  10480.                 -- s stores the agent id and min subscription_seqno for
  10481.                 -- active well known subscriptions
  10482.                 (select s2.agent_id, min(s2.subscription_seqno) from
  10483.                     MSsubscriptions s2 
  10484.                     where
  10485.                     s2.status = @active and
  10486.                     -- Only well-known agent
  10487.                     s2.subscriber_id >= 0
  10488.                     group by s2.agent_id)
  10489.                 s (agent_id, subscription_seqno)
  10490.                 left join MSdistribution_history h
  10491.                 on (h.agent_id = s.agent_id)
  10492.                 group by s.agent_id, s.subscription_seqno)
  10493.             sh (agent_id, subscription_seqno, timestamp)
  10494.             left join MSdistribution_history dh 
  10495.             on (dh.agent_id = sh.agent_id and dh.timestamp = sh.timestamp)
  10496.             -- a is for publisher_database_id
  10497.             join MSdistribution_agents a
  10498.             on (a.id = sh.agent_id)
  10499.             where
  10500.             @cutoff_time > = (
  10501.                 -- Get the entry_time of the first tran that cannot be
  10502.                 -- cleaned up normally because of this agent.
  10503.                 -- Use history if it's larger and it is not null (exists)
  10504.                 case  when dh.xact_seqno >= sh.subscription_seqno 
  10505.                 then
  10506.                     -- Have to join with commands table because transactions that
  10507.                     -- does not have commands will not be picked up by
  10508.                     -- sp_MSget_repl_commands
  10509.                     isnull((select top 1 entry_time from MSrepl_transactions t,
  10510.                         MSrepl_commands c where
  10511.                         t.publisher_database_id = a.publisher_database_id and
  10512.                         c.publisher_database_id = a.publisher_database_id and
  10513.                         c.xact_seqno = t.xact_seqno and
  10514.                         -- history xact_seqno can be cleaned up
  10515.                         t.xact_seqno > isnull(dh.xact_seqno,0x0) and
  10516.                         c.xact_seqno > isnull(dh.xact_seqno,0x0)
  10517.                         order by t.xact_seqno asc), @max_time)
  10518.                 else
  10519.                     isnull((select top 1 entry_time from MSrepl_transactions t,
  10520.                         MSrepl_commands c where
  10521.                         t.publisher_database_id = a.publisher_database_id and
  10522.                         c.publisher_database_id = a.publisher_database_id and
  10523.                         c.xact_seqno = t.xact_seqno and
  10524.                         -- sub xact_seqno cannot be cleaned up
  10525.                         t.xact_seqno >= sh.subscription_seqno and
  10526.                         c.xact_seqno >= sh.subscription_seqno                
  10527.                         order by t.xact_seqno asc), @max_time)
  10528.                 end))
  10529.  
  10530.     if @@rowcount <> 0
  10531.         RAISERROR(21011, 10, -1) 
  10532.  
  10533.     -- Dropping all the aonymous agents that are working on
  10534.     -- transactions that are older than @retention
  10535.     -- No message raised.
  10536.     -- Don't drop agents that do not have history (true for new agents).
  10537.     -- For each publisher/publisherdb pair do cleanup
  10538.     declare hC CURSOR LOCAL FAST_FORWARD FOR 
  10539.         select distinct a.id from 
  10540.             (select s.agent_id, s.subscription_seqno, max(isnull(h.timestamp,0x00))
  10541.                 from 
  10542.                 -- s stores the agent id and min subscription_seqno for
  10543.                 -- active anonymous subscriptions
  10544.                 (select a2.id, min(s2.subscription_seqno) from
  10545.                     MSsubscriptions s2 
  10546.                     join MSdistribution_agents a2
  10547.                     on (a2.anonymous_agent_id = s2.agent_id)
  10548.                     where
  10549.                     s2.status = @active 
  10550.                     group by a2.id)
  10551.                 s (agent_id, subscription_seqno)
  10552.                 join MSdistribution_history h
  10553.                 on (h.agent_id = s.agent_id)
  10554.                 group by s.agent_id, s.subscription_seqno)
  10555.             sh (agent_id, subscription_seqno, timestamp)
  10556.             join MSdistribution_history dh 
  10557.             on (dh.agent_id = sh.agent_id and dh.timestamp = sh.timestamp)
  10558.             join MSdistribution_agents a
  10559.             -- a is for publisher_database_id
  10560.             on (a.id = sh.agent_id)
  10561.             where
  10562.             @cutoff_time > = (
  10563.                 -- Get the entry_time of the first tran that cannot be
  10564.                 -- cleaned up normally because of this agent.
  10565.                 -- Use history if it's larger and it is not null (exists)
  10566.                 case  when dh.xact_seqno >= sh.subscription_seqno 
  10567.                 then
  10568.                     -- does not have commands will not be picked up by
  10569.                     -- sp_MSget_repl_commands
  10570.                     isnull((select top 1 entry_time from MSrepl_transactions t,
  10571.                         MSrepl_commands c where
  10572.                         t.publisher_database_id = a.publisher_database_id and
  10573.                         c.publisher_database_id = a.publisher_database_id and
  10574.                         c.xact_seqno = t.xact_seqno and
  10575.                         -- history xact_seqno can be cleaned up
  10576.                         t.xact_seqno > isnull(dh.xact_seqno,0x0) and
  10577.                         c.xact_seqno > isnull(dh.xact_seqno,0x0)
  10578.                         order by t.xact_seqno asc), @max_time)
  10579.                 else
  10580.                     isnull((select top 1 entry_time from MSrepl_transactions t,
  10581.                         MSrepl_commands c where
  10582.                         t.publisher_database_id = a.publisher_database_id and
  10583.                         c.publisher_database_id = a.publisher_database_id and
  10584.                         c.xact_seqno = t.xact_seqno and
  10585.                         -- sub xact_seqno cannot be cleaned up
  10586.                         t.xact_seqno >= sh.subscription_seqno and
  10587.                         c.xact_seqno >= sh.subscription_seqno
  10588.                         order by t.xact_seqno asc), @max_time)
  10589.                   end)
  10590.     for read only
  10591.     open hC
  10592.     fetch hC into @agent_id
  10593.     while (@@fetch_status <> -1)
  10594.     begin
  10595.         exec @retcode = dbo.sp_MSdrop_distribution_agentid @agent_id
  10596.         if @retcode <> 0 or @@error <> 0
  10597.             return (1)
  10598.         fetch hC into @agent_id
  10599.     end
  10600.  
  10601.     -- Deactivating subscriptions virtual subscriptions that are older then @retention.
  10602.     update MSsubscriptions  set status = @subscribed
  10603.         where
  10604.         -- Only change active subscriptions!
  10605.         status = @active and 
  10606.         subscriber_id = @virtual and
  10607.                 -- Get the entry_time of the first tran that cannot be
  10608.                 -- cleaned up normally because of this subscription.
  10609.             isnull((select top 1 entry_time from MSrepl_transactions t where
  10610.                 t.publisher_database_id = MSsubscriptions.publisher_database_id and
  10611.                 xact_seqno >= MSsubscriptions.subscription_seqno
  10612.                 order by t.xact_seqno asc), @max_time)
  10613.             <= @cutoff_time
  10614.     if @@rowcount <> 0
  10615.         RAISERROR(21077, 10, -1) 
  10616. GO
  10617.  
  10618. raiserror(15339,-1,-1,'sp_MSdrop_snapshot_dirs')
  10619. GO
  10620. CREATE PROCEDURE sp_MSdrop_snapshot_dirs
  10621. as
  10622.     declare @retcode int
  10623.     declare @snapshot_bit int
  10624.     declare @directory_type int
  10625.     declare @publisher_database_id int
  10626.         
  10627.     declare @dir nvarchar(512)
  10628.     declare @command_id int
  10629.     declare @xact_seqno varbinary(16)
  10630.     declare @delcmd nvarchar(524)
  10631.  
  10632.     select @snapshot_bit = 0x80000000
  10633.     select @directory_type = 7
  10634.  
  10635.     declare  hCdirs  CURSOR LOCAL FAST_FORWARD FOR select CONVERT(nvarchar(512), command),
  10636.         xact_seqno, command_id, publisher_database_id
  10637.         from MSrepl_commands where
  10638.         (type & ~@snapshot_bit) = @directory_type
  10639.     for read only
  10640.  
  10641.     open hCdirs
  10642.     fetch hCdirs into @dir, @xact_seqno, @command_id, @publisher_database_id
  10643.     while (@@fetch_status <> -1)
  10644.     begin
  10645.         select @delcmd = 'if exist "' + @dir + '" rmdir /S /Q "' + @dir + '"' 
  10646.         exec @retcode = master..xp_cmdshell @delcmd
  10647.         /* Abort the operation if the delete fails */
  10648.         if (@retcode <> 0 or @@error <> 0)
  10649.         begin
  10650.             raiserror(20015, 16, -1, @dir)
  10651.             return (1)
  10652.         end
  10653.  
  10654.         delete MSrepl_commands where 
  10655.             publisher_database_id = @publisher_database_id and
  10656.             xact_seqno = @xact_seqno and
  10657.             command_id = @command_id
  10658.  
  10659.         fetch hCdirs into @dir, @xact_seqno, @command_id, @publisher_database_id
  10660.     end
  10661.     close hCdirs
  10662.     deallocate hCdirs
  10663. GO
  10664.  
  10665. raiserror(15339,-1,-1,'sp_MSfast_delete_trans')
  10666. GO
  10667. CREATE PROCEDURE sp_MSfast_delete_trans
  10668. as
  10669.     declare @retcode int
  10670.  
  10671.     EXEC @retcode = sp_MSdrop_snapshot_dirs
  10672.     if( @retcode <> 0 or @@error <> 0 )
  10673.         return 1
  10674.  
  10675.     truncate table MSrepl_commands
  10676.     truncate table MSrepl_transactions
  10677.  
  10678. GO
  10679. raiserror(15339,-1,-1,'sp_MSdelete_publisherdb_trans')
  10680. GO
  10681. CREATE PROCEDURE sp_MSdelete_publisherdb_trans
  10682.     @publisher_database_id int,
  10683.     @max_xact_seqno varbinary(16),
  10684.     @max_cutoff_time datetime,
  10685.     @num_transactions int OUTPUT,
  10686.     @num_commands int OUTPUT
  10687.     as
  10688.  
  10689.     set nocount on
  10690.     
  10691.     declare @snapshot_bit int
  10692.     declare @directory_type int
  10693.     declare @last_xact_seqno varbinary(16)
  10694.     declare @last_log_xact_seqno varbinary(16)
  10695.     declare @max_immediate_sync_seqno varbinary(16)
  10696.     declare @delcmd nvarchar(524)
  10697.     declare @dir nvarchar(512)
  10698.     declare @row_count int
  10699.     declare @batchsize int
  10700.     declare @retcode int            /* Return value of xp_cmdshell */
  10701.     declare @has_immediate_sync bit
  10702.     declare @xact_seqno varbinary(16)
  10703.     declare @command_id int
  10704.  
  10705.     select @snapshot_bit = 0x80000000
  10706.     select @directory_type = 7
  10707.     select @num_transactions = 0
  10708.     select @num_commands = 0
  10709.  
  10710.     -- If transactions for immediate_sync publications will not be cleanup up until
  10711.     -- they are older that max retention, except for snapshot transactions.
  10712.     -- Snapshot transactions for immediate_sync publication will be cleanup up if it is
  10713.     -- not used by any subscriptions (including virtual and virtual immediate_syncymous
  10714.     -- subscriptions. Both will be reset by snapshot agent every time if the 
  10715.     -- publication is snapshot type.) The special logic for snapshot transactions
  10716.     -- is mostly for snapshop publications. It is to cleaup up the snapshot files 
  10717.     -- ASAP and not to wait for max retention.
  10718.     -- We don't need to do this for non-immediate_syncymous publications since the snapshot
  10719.     -- trans for them will be removed as soon as they are distributed and min '
  10720.     -- retention is reached.
  10721.  
  10722.     -- Detect if there are immediate_syncymous publications in this publishing db.
  10723.     if exists (select * from MSsubscriptions where
  10724.             publisher_database_id = @publisher_database_id and
  10725.             subscriber_id < 0)
  10726.         select @has_immediate_sync = 1
  10727.     else
  10728.         select @has_immediate_sync = 0
  10729.  
  10730.     if @has_immediate_sync = 1
  10731.     begin
  10732.         -- if @max_immediate_sync_seqno is null, not row will be deleted based on that.
  10733.         select @max_immediate_sync_seqno = max(xact_seqno) from MSrepl_transactions where
  10734.             publisher_database_id = @publisher_database_id and
  10735.             entry_time <= @max_cutoff_time
  10736.     end
  10737.  
  10738.     -- Note delete commands first since transaction table will be used for
  10739.     -- geting @max_xact_seqno (see sp_MSmaximum_cleanup_seqno).
  10740.     -- Delete all directories stored in directory command.
  10741.     if @has_immediate_sync = 0
  10742.         declare  hCdirs  CURSOR LOCAL FAST_FORWARD FOR select CONVERT(nvarchar(512), command),
  10743.             xact_seqno, command_id
  10744.             from MSrepl_commands where
  10745.             publisher_database_id = @publisher_database_id and
  10746.             xact_seqno <= @max_xact_seqno and   
  10747.             (type & ~@snapshot_bit) = @directory_type
  10748.         for read only
  10749.     else
  10750.         declare  hCdirs  CURSOR LOCAL FAST_FORWARD FOR select CONVERT(nvarchar(512), command),
  10751.             xact_seqno, command_id
  10752.             from MSrepl_commands c where
  10753.             publisher_database_id = @publisher_database_id and
  10754.             (type & ~@snapshot_bit) = @directory_type and
  10755.             xact_seqno <= @max_xact_seqno and  
  10756.             (
  10757.             -- Select the row if it is older than max retention.
  10758.             xact_seqno <= @max_immediate_sync_seqno or 
  10759.             -- Select the row if it is not used by any subscriptions.
  10760.             not exists (select * from MSsubscriptions s where
  10761.                 s.publisher_database_id = @publisher_database_id and
  10762.                 s.subscription_seqno = c.xact_seqno) OR
  10763.             -- Select the row if it is not for immediate_sync publications
  10764.             -- Note: directory command have article id 0 so it is not useful
  10765.             not exists (select * from MSpublications p where
  10766.                 p.publication_id = (select top 1 s.publication_id 
  10767.                     from MSsubscriptions s where
  10768.                     s.publisher_database_id = @publisher_database_id and
  10769.                     s.subscription_seqno = c.xact_seqno) and
  10770.                 p.immediate_sync = 1)
  10771.             )
  10772.         for read only
  10773.  
  10774.     open hCdirs
  10775.     fetch hCdirs into @dir, @xact_seqno, @command_id
  10776.     while (@@fetch_status <> -1)
  10777.     begin
  10778.         select @delcmd = 'if exist "' + @dir + '" rmdir /S /Q "' + @dir + '"' 
  10779.         exec @retcode = master..xp_cmdshell @delcmd
  10780.         /* Abort the operation if the delete fails */
  10781.         if (@retcode <> 0 or @@error <> 0)
  10782.         begin
  10783.             raiserror(20015, 16, -1, @dir)
  10784.             return (1)
  10785.         end
  10786.  
  10787.         delete MSrepl_commands where 
  10788.             publisher_database_id = @publisher_database_id and
  10789.             xact_seqno = @xact_seqno and
  10790.             command_id = @command_id
  10791.         -- Update output parameter
  10792.         select @num_commands = @num_commands + @@rowcount
  10793.  
  10794.         fetch hCdirs into @dir, @xact_seqno, @command_id
  10795.     end
  10796.     close hCdirs
  10797.     deallocate hCdirs
  10798.  
  10799.  
  10800.     -- Delete all commans less than or equal to the @max_xact_seqno
  10801.     -- Delete in batch to reduce the transaction size
  10802.     set rowcount 2000
  10803.     WHILE 1 = 1
  10804.     BEGIN
  10805.         if @has_immediate_sync = 0
  10806.             DELETE MSrepl_commands WITH (PAGLOCK) where
  10807.                 publisher_database_id = @publisher_database_id and
  10808.                 xact_seqno <= @max_xact_seqno
  10809.         else
  10810.             -- Use nolock hint on subscription table to avoid deadlock
  10811.             -- with snapshot agent.
  10812.             DELETE MSrepl_commands WITH (PAGLOCK) where
  10813.                 publisher_database_id = @publisher_database_id and
  10814.                 xact_seqno <= @max_xact_seqno and
  10815.                 -- Don't delete directory commands. It is deleted ealier.
  10816.                 -- We have to do this because we use (nolock) hint. we have to make sure
  10817.                 -- we don't delete dir command when the file is not cleaned up in the code
  10818.                 -- above.
  10819.                 (type & ~@snapshot_bit) <> @directory_type and
  10820.                 (
  10821.                 -- Select the row if it is older than max retention.
  10822.                 xact_seqno <= @max_immediate_sync_seqno or 
  10823.                 -- Select the row if it is not for immediate_sync article
  10824.                 -- We know the command is for immediate_sync publication if
  10825.                 -- the snapshot tran include articles that has virtual
  10826.                 -- subscritptions. (use subscritpion table to avoid join with
  10827.                 -- article and publication table)
  10828.                 not exists (select * from MSsubscriptions s (nolock) where
  10829.                     s.publisher_database_id = @publisher_database_id and
  10830.                     s.article_id = MSrepl_commands.article_id and
  10831.                     s.subscriber_id < 0) or
  10832.                 -- Select the row if it is snapshot tran and 
  10833.                 -- not used by any subscriptions.
  10834.                 ((type & @snapshot_bit) <> 0 and
  10835.                 not exists (select * from MSsubscriptions s (nolock) where
  10836.                     s.publisher_database_id = @publisher_database_id and
  10837.                     s.subscription_seqno = MSrepl_commands.xact_seqno))
  10838.                 )
  10839.  
  10840.         select @row_count = @@rowcount
  10841.         -- Update output parameter
  10842.         select @num_commands = @num_commands + @row_count
  10843.     
  10844.         IF @row_count = 0 -- passed the result set.  We're done
  10845.             BREAK
  10846.     END
  10847.  
  10848.     -- Optimized query to get the max transaction row
  10849.     set rowcount 1
  10850.     select @last_log_xact_seqno = xact_seqno from MSrepl_transactions
  10851.         where
  10852.             publisher_database_id = @publisher_database_id and
  10853.             xact_id <> 0x0  -- not initial sync transaction
  10854.             order by xact_seqno desc
  10855.  
  10856.     select @last_xact_seqno = xact_seqno from MSrepl_transactions
  10857.         where
  10858.             publisher_database_id = @publisher_database_id
  10859.             order by xact_seqno desc
  10860.     set rowcount 0
  10861.  
  10862.     -- Remove all transactions less than or equal to the @max_xact_seqno and leave the 
  10863.     -- last transaction row
  10864.     -- Note @max_xact_seqno might be null, in this case don't do any thing.
  10865.     -- Delete in batchs to reduce the transaction size
  10866.     set rowcount 5000
  10867.     -- Delete all commans less than or equal to the @max_xact_seqno
  10868.     -- Delete  rows to reduce the transaction size
  10869.     WHILE 1 = 1
  10870.     BEGIN
  10871.         if @has_immediate_sync = 0
  10872.             delete MSrepl_transactions WITH (PAGLOCK) from MSrepl_transactions where
  10873.                 publisher_database_id = @publisher_database_id and
  10874.                 xact_seqno <= @max_xact_seqno and
  10875.                 xact_seqno <> @last_xact_seqno and
  10876.                 xact_seqno <> @last_log_xact_seqno
  10877.         else
  10878.             delete MSrepl_transactions WITH (PAGLOCK) from MSrepl_transactions where
  10879.                 publisher_database_id = @publisher_database_id and
  10880.                 xact_seqno <= @max_xact_seqno and
  10881.                 xact_seqno <> @last_xact_seqno and
  10882.                 xact_seqno <> @last_log_xact_seqno and
  10883.                 -- use nolock to avoid deadlock
  10884.                 not exists (select * from MSrepl_commands c (nolock) where
  10885.                     c.publisher_database_id = @publisher_database_id and
  10886.                     c.xact_seqno = MSrepl_transactions.xact_seqno)
  10887.  
  10888.         select @row_count = @@rowcount
  10889.  
  10890.         -- Update output parameter
  10891.         select @num_transactions = @num_transactions + @row_count
  10892.         if @row_count = 0
  10893.             BREAK
  10894.     END
  10895.     set rowcount 0
  10896. GO
  10897.  
  10898.  
  10899. raiserror(15339,-1,-1,'sp_MSmaximum_cleanup_seqno')
  10900. go
  10901. CREATE PROCEDURE sp_MSmaximum_cleanup_seqno
  10902.     @publisher_database_id int,
  10903.     @min_cutoff_time datetime,
  10904.     @max_cleanup_xact_seqno varbinary(16) OUTPUT
  10905.     as
  10906.  
  10907.     declare @min_sub_xact_seqno varbinary(16)
  10908.     declare @min_history_xact_seqno varbinary(16)
  10909.     declare @active int
  10910.     declare @max_seqno varbinary(16)
  10911.     
  10912.     -- @max_seqn is to avoid warnging message from server on null values in aggregation.
  10913.     select @max_seqno = 0xffffffffffffffffffffffffffffffff
  10914.  
  10915.     set nocount on
  10916.  
  10917.     select @active = 2
  10918.  
  10919.     select  
  10920.         -- Get the min history xact_seqno that are large then or equal to starting
  10921.         -- sub seqno
  10922.         @min_history_xact_seqno = min(seqno.xact_seqno), 
  10923.         -- Get the min starting sub xact_seqno without larger history xact_seqno or without
  10924.         -- any history at all.
  10925.         @min_sub_xact_seqno = min(seqno.subscription_seqno)
  10926.         from
  10927.             -- seqno stores min sub seqno , min history seqno and choose_sub
  10928.             (select 
  10929.                 -- If history is larger and it is not null
  10930.                 -- use history.
  10931.                 case when dh.xact_seqno > = sh.subscription_seqno 
  10932.                 then dh.xact_seqno
  10933.                 -- Don't use dh in else
  10934.                 else @max_seqno
  10935.                 end,
  10936.  
  10937.                 -- If history is larger and it is not null
  10938.                 -- use history.
  10939.                 case when dh.xact_seqno > = sh.subscription_seqno 
  10940.                 -- Don't use sh
  10941.                 then @max_seqno
  10942.                 else sh.subscription_seqno
  10943.                 end
  10944.  
  10945.                 from 
  10946.                     (select s.agent_id, s.subscription_seqno, max(isnull(h.timestamp,0x00))
  10947.                     from 
  10948.                         -- s stores the agent id and min subscription_seqno for
  10949.                         -- active subscriptions on non immediate_sync subscriptions
  10950.                         (select a.id, min(s2.subscription_seqno) from
  10951.                             MSsubscriptions s2 
  10952.                             join MSdistribution_agents a
  10953.                             on (a.id = s2.agent_id) 
  10954.                             where
  10955.                             s2.status = @active and
  10956.                             /* Note must filter out virtual anonymous agents !!!
  10957.                                 a.subscriber_id <> @virtual_anonymous and */
  10958.                             -- filter out subscriptions to immediate_sync publications
  10959.                             not exists (select * from MSpublications p where
  10960.                                 s2.publication_id = p.publication_id and
  10961.                                 p.immediate_sync = 1) and
  10962.                             a.publisher_database_id = @publisher_database_id
  10963.                             group by a.id)
  10964.                         s (agent_id, subscription_seqno)
  10965.                         left join MSdistribution_history h
  10966.                         on (h.agent_id = s.agent_id)
  10967.                         group by s.agent_id, s.subscription_seqno)
  10968.                     sh (agent_id, subscription_seqno, timestamp)
  10969.                     left join MSdistribution_history dh 
  10970.                     on (dh.agent_id = sh.agent_id and dh.timestamp = sh.timestamp))
  10971.                     seqno (xact_seqno, subscription_seqno)
  10972.  
  10973.  
  10974.  
  10975. /*  This version might be faster.. Need experiments.
  10976.  
  10977.  
  10978.     -- Get the min history xact_seqno that are large then or equal to starting
  10979.     -- sub seqno
  10980.     select @min_history_xact_seqno = min(dh.xact_seqno) from
  10981.         -- h stores the agent_ids and last xact_seqno for the publisher_db 
  10982.         (select h2.agent_id, max(h2.timestamp) 
  10983.             from MSdistribution_history h2
  10984.             join MSdistribution_agents a
  10985.                 on (a.id = h2.agent_id)
  10986.             where
  10987.                 a.publisher_database_id = @publisher_database_id
  10988.                 group by h2.agent_id)
  10989.         h (agent_id, timestamp) 
  10990.         -- dh stores timestamp and xact_seqno association
  10991.         join MSdistribution_history dh 
  10992.             on (dh.agent_id = h.agent_id and dh.timestamp = h.timestamp)
  10993.         where   
  10994.             -- Only select history xact seqno larger then or equal to
  10995.             -- subscription start up seqno.
  10996.             -- Excluding agents with no active subscriptions. 
  10997.             dh.xact_seqno >=
  10998.                 (select min(s.subscription_seqno) from MSsubscritions s where
  10999.                     -- Including anonymous agents
  11000.                     (s.agent_id = a. agent_id or s.agent_id = a.anonymous_agent_id) and
  11001.                     s.status = @active)
  11002.             
  11003.     -- Get the min starting sub xact_seqno without larger history xact_seqno or without
  11004.     -- any history at all.
  11005.     -- This will happen if the subscription is reinited
  11006.     -- excluding virtual anonymous subscriptions.
  11007.     select @min_sub_xact_seqno = min(s.subscription_seqno) from
  11008.         MSsubscriptions s
  11009.         -- left join so that subscription without history will be included. 
  11010.         left join ((select h2.agent_id, max(h2.timestamp) 
  11011.             from MSdistribution_history h2
  11012.             join MSdistribution_agents a
  11013.                 on (a.id = h2.agent_id)
  11014.             where
  11015.                 a.publisher_database_id = @publisher_database_id
  11016.                 group by h2.agent_id)
  11017.             h (agent_id, timestamp) 
  11018.         -- dh stores timestamp and xact_seqno association
  11019.         join MSdistribution_history dh 
  11020.             on (dh.agent_id = h.agent_id and dh.timestamp = h.timestamp))
  11021.             on (s.agent_id = h.agent_id)
  11022.         where
  11023.         s.status = @active and
  11024.         s.subscriber_id <> @virtual_anonymous and
  11025.         s.publisher_database_id = @publisher_database_id and
  11026.         -- select only subs that has a larger starting seqno than history last seqno
  11027.         -- or with no history
  11028.         s.subscription_seqno > isnull(dh.xact_seqno, 0x0)
  11029. */  
  11030.     
  11031.     /* 
  11032.     ** Optimized query to get the maximum cleanup xact_seqno
  11033.     */
  11034.     /* 
  11035.     ** If the query below returns nothing, nothing can be deleted.
  11036.     ** Reset @max_cleanup_xact_seqno to 0.
  11037.     */
  11038.     select @max_cleanup_xact_seqno = 0x00
  11039.     -- Use top 1 to avoid warning message of "Null in aggregate..." which will make
  11040.     -- sqlserver agent job having failing status
  11041.     select top 1 @max_cleanup_xact_seqno = xact_seqno
  11042.         from MSrepl_transactions
  11043.         where
  11044.             publisher_database_id = @publisher_database_id and
  11045.             (@min_history_xact_seqno IS NULL or
  11046.             -- Delete the history xact since it is distributed already.
  11047.             xact_seqno <= @min_history_xact_seqno) and
  11048.             (@min_sub_xact_seqno IS NULL or
  11049.             -- Don't delete the sub xact since it is not distributed yet.
  11050.             xact_seqno < @min_sub_xact_seqno) and
  11051.             entry_time <= @min_cutoff_time
  11052.             order by xact_seqno desc
  11053.  
  11054. GO
  11055.  
  11056. raiserror(15339,-1,-1,'sp_MSdistribution_delete')
  11057. go
  11058. CREATE PROCEDURE sp_MSdistribution_delete
  11059.     @retention int = 0,
  11060.     -- Used for anon publications.
  11061.     @max_cutoff_time datetime
  11062.     as
  11063.     declare @min_cutoff_time datetime
  11064.     declare @subscriber sysname
  11065.     declare @subscriber_db sysname
  11066.     declare @max_cleanup_xact_seqno varbinary(16)   
  11067.     declare @num_transactions int
  11068.     declare @num_commands int
  11069.     declare @start_time datetime
  11070.     declare @num_seconds int
  11071.     declare @rate int
  11072.     declare @retcode int
  11073.     declare @publisher_database_id int
  11074.  
  11075.     set nocount on
  11076.  
  11077.     select @num_transactions = 0
  11078.     select @num_commands = 0
  11079.  
  11080.     select @start_time = getdate()
  11081.     select @min_cutoff_time = dateadd(hour, -@retention, getdate())
  11082.  
  11083.     -- For each publisher/publisherdb pair do cleanup
  11084.     declare hC CURSOR LOCAL FAST_FORWARD FOR select distinct publisher_database_id
  11085.         from MSrepl_transactions
  11086.         for read only
  11087.     -- With ANSI Defaults ON, the cursor will automatically
  11088.     -- be closed on commit.   Since this proc gets called recursively, 
  11089.     -- this can happen.  So check before opening. 
  11090.     IF CURSOR_STATUS('local','hC') = -1
  11091.     open hC
  11092.  
  11093.     fetch hC into @publisher_database_id 
  11094.     while (@@fetch_status <> -1)
  11095.     begin
  11096.  
  11097.         -- Find the maximum transaction to delete
  11098.         exec @retcode = dbo.sp_MSmaximum_cleanup_seqno @publisher_database_id, @min_cutoff_time, @max_cleanup_xact_seqno OUTPUT
  11099.         if @retcode <> 0
  11100.             goto FAIL           
  11101.  
  11102.         -- Delete transactions and commands
  11103.         exec @retcode = dbo.sp_MSdelete_publisherdb_trans @publisher_database_id, 
  11104.             @max_cleanup_xact_seqno, @max_cutoff_time,
  11105.             @num_transactions OUTPUT, @num_commands OUTPUT
  11106.         if @retcode <> 0
  11107.             goto FAIL
  11108.  
  11109.         IF CURSOR_STATUS('local','hC') = -1
  11110.             open hC
  11111.         
  11112.         fetch hC into @publisher_database_id 
  11113.     end
  11114.     close hC
  11115.     deallocate hC
  11116.  
  11117.     select @num_seconds = datediff(second, @start_time, getdate())
  11118.     if @num_seconds <> 0 
  11119.       select @rate = (@num_transactions+@num_commands)/@num_seconds
  11120.     else
  11121.       select @rate = 0
  11122.  
  11123.    RAISERROR(21010, 10, -1, @num_transactions, @num_commands, @num_seconds, @rate)
  11124.  
  11125.    return 0
  11126.  
  11127. FAIL:
  11128.    close hC
  11129.    deallocate hC
  11130.    return 1
  11131. GO
  11132.  
  11133.  
  11134. raiserror(15339,-1,-1,'sp_MSdistribution_cleanup')
  11135. GO
  11136. CREATE PROCEDURE sp_MSdistribution_cleanup
  11137.     @min_distretention int = 0,
  11138.     @max_distretention int = 24
  11139.     as
  11140.  
  11141.     declare @retcode int
  11142.     declare @agent_name nvarchar(255)
  11143.     declare @agent_type nvarchar(100)
  11144.     declare @message nvarchar(255)
  11145.     declare @cutoff_time datetime
  11146.  
  11147.      -- Check for invalid parameter values 
  11148.     if @min_distretention < 0 or @max_distretention < 0
  11149.     begin
  11150.         RAISERROR(14106, 16, -1)
  11151.         return (1)
  11152.     end
  11153.  
  11154.     -- Note: we need to use the same cut_off time for sp_MSsubscription_cleanup
  11155.     -- and sp_MSdistribution_delete since sp_MSsubscription_cleanup need to disable
  11156.     -- all the dist agents that are lag behind (their pending trans will be removed)
  11157.     select @cutoff_time = dateadd(hour, -@max_distretention, getdate())
  11158.  
  11159.     -- Deactive any subscriptions which have been inactive beyond the maximum retention
  11160.     exec @retcode = dbo.sp_MSsubscription_cleanup @cutoff_time
  11161.     if @retcode <> 0
  11162.         goto FAIL
  11163.  
  11164.     -- Remove transactions and commands
  11165.     exec @retcode = dbo.sp_MSdistribution_delete @min_distretention, 
  11166.         -- used to cleanup trans for anon publications.
  11167.         @cutoff_time
  11168.     if @retcode <> 0
  11169.         goto FAIL
  11170.  
  11171.     -- Update statistics on cleaned tables with norecompute flag
  11172.     -- to both update the statistics periodically and 
  11173.     -- to ensure that they are not updated too frequently
  11174.     -- since this slows performance.
  11175.     --
  11176.     -- Update statistics can only be performed when not in
  11177.     -- not in a tracation so predicate by transaction level
  11178.     -- to avoid error.
  11179.     --
  11180.     if @@trancount = 0
  11181.     begin
  11182.         UPDATE STATISTICS MSrepl_commands WITH NORECOMPUTE
  11183.         UPDATE STATISTICS MSrepl_transactions WITH NORECOMPUTE
  11184.     end
  11185.  
  11186.     return(0)
  11187.  
  11188. FAIL:
  11189.     -- Raise the Agent Failure error
  11190.     set @agent_type  = formatmessage(20543)
  11191.     SELECT @agent_name = db_name() + @agent_type
  11192.     set @message  = formatmessage(20552)
  11193.     exec dbo.sp_MSrepl_raiserror @agent_type, @agent_name, 5, @message
  11194.     return (1)  
  11195.  
  11196. GO
  11197.  
  11198. raiserror(15339,-1,-1,'sp_MShistory_cleanup')
  11199. GO
  11200. CREATE PROCEDURE sp_MShistory_cleanup
  11201. @history_retention int = 24
  11202. as
  11203.     declare @cutoff_time datetime
  11204.     declare @start_time datetime
  11205.     declare @num_snapshot_rows int
  11206.     declare @num_logreader_rows int
  11207.     declare @num_distribution_rows int
  11208.     declare @num_replerror_rows int
  11209.     declare @num_milliseconds int
  11210.     declare @num_seconds float
  11211.     declare @seconds_str nvarchar(10)
  11212.     declare @rate int
  11213.     declare @retcode int
  11214.     declare @total_rows int
  11215.     declare @num_merge_rows int
  11216.     declare @agent_name nvarchar(255)
  11217.     declare @agent_type nvarchar(100)
  11218.     declare @message nvarchar(255)
  11219.     declare @agent_id int
  11220.     declare @temp_error int
  11221.  
  11222.     set nocount on
  11223.  
  11224.     /* Check for invalid parameter values */
  11225.     if @history_retention < 0
  11226.     BEGIN
  11227.         RAISERROR(14106, 16, -1)
  11228.         RETURN (1)
  11229.     END
  11230.     
  11231.     -- Get start time for statistics at the end
  11232.     select @start_time = getdate()
  11233.  
  11234.     select @num_snapshot_rows = 0
  11235.     select @num_logreader_rows = 0
  11236.     select @num_distribution_rows = 0
  11237.     select @num_merge_rows = 0
  11238.     select @num_replerror_rows = 0
  11239.  
  11240.     -- Get cutoff time
  11241.     select @cutoff_time = dateadd(hour, -@history_retention, getdate())
  11242.  
  11243.     -- Delete sp_MSsnapshot_history (leave at least one row for monitoring)
  11244.     delete MSsnapshot_history where 
  11245.         time <= @cutoff_time and
  11246.         timestamp not in (select max(timestamp) from MSsnapshot_history 
  11247.             group by agent_id)
  11248.     select @temp_error = @@error, @num_snapshot_rows = @num_snapshot_rows + @@rowcount
  11249.     if @temp_error <> 0
  11250.         goto FAIL
  11251.  
  11252.     -- Delete sp_MSsnapshot_history that no longer has an MSsnapshot_agent entry
  11253.     delete from MSsnapshot_history where not exists (select * from MSsnapshot_agents
  11254.         where id = agent_id)
  11255.     select @temp_error = @@error, @num_snapshot_rows = @num_snapshot_rows + @@rowcount
  11256.     if @temp_error <> 0
  11257.         goto FAIL
  11258.  
  11259.     -- Delete sp_MSlogreader_history (leave at least one row for monitoring)
  11260.     delete MSlogreader_history where 
  11261.         time <= @cutoff_time and
  11262.         timestamp not in (select max(timestamp) from MSlogreader_history 
  11263.             group by agent_id)
  11264.     select @temp_error = @@error, @num_logreader_rows = @num_logreader_rows + @@rowcount
  11265.     if @temp_error <> 0
  11266.         goto FAIL
  11267.  
  11268.     -- Delete sp_MSlogreader_history that no longer has an MSlogreader_agent entry
  11269.     delete from MSlogreader_history where not exists (select * from MSlogreader_agents
  11270.         where id = agent_id)
  11271.     select @temp_error = @@error, @num_logreader_rows = @num_logreader_rows + @@rowcount
  11272.     if @temp_error <> 0
  11273.         goto FAIL
  11274.  
  11275.     -- Delete sp_MSdistribution_history (leave at least one row for monitoring)
  11276.     -- Leave last record ONLY if the agent is not anonymous.  The current logic is to remove all history for anonymous
  11277.     -- subscription, the agent definition will also be removed below.
  11278.     delete MSdistribution_history where 
  11279.         time <= @cutoff_time and
  11280.         timestamp not in (select max(timestamp) from MSdistribution_history group by agent_id)
  11281.     select @temp_error = @@error, @num_distribution_rows = @num_distribution_rows + @@rowcount
  11282.     if @temp_error <> 0
  11283.         goto FAIL
  11284.  
  11285.     -- Delete sp_MSdistribution_history that no longer has an MSdistribution_agent entry
  11286.     delete MSdistribution_history from MSdistribution_history dh where not exists (select * from MSdistribution_agents
  11287.         where id = dh.agent_id)
  11288.     select @temp_error = @@error, @num_distribution_rows = @num_distribution_rows + @@rowcount
  11289.     if @temp_error <> 0
  11290.         goto FAIL
  11291.  
  11292.     -- Delete sp_MSmerge_history (leave at least one row for monitoring)
  11293.     -- Leave last record ONLY if the agent is not anonymous.  The current logic is to remove all history for anonymous
  11294.     -- subscription, the agent definition will also be removed below.
  11295.     delete from MSmerge_history where 
  11296.         time <= @cutoff_time and
  11297.         timestamp not in (select max(timestamp) from MSmerge_history group by agent_id)
  11298.     select @temp_error = @@error, @num_merge_rows = @num_merge_rows + @@rowcount
  11299.     if @temp_error <> 0
  11300.         goto FAIL
  11301.  
  11302.     -- Delete sp_MSmerge_history that no longer has an MSmerge_agent entry
  11303.     delete from MSmerge_history where not exists (select * from MSmerge_agents where id = agent_id)
  11304.     select @temp_error = @@error, @num_merge_rows = @num_merge_rows + @@rowcount
  11305.     if @temp_error <> 0
  11306.         goto FAIL
  11307.  
  11308.     -- Delete MSrepl_error entries
  11309.     delete from MSrepl_errors where time <= @cutoff_time 
  11310.     select @temp_error = @@error, @num_replerror_rows = @@rowcount
  11311.     if @temp_error <> 0
  11312.         goto FAIL
  11313.  
  11314.     -- Calculate statistics for number of rows deleted
  11315.     select @num_milliseconds = datediff(millisecond, @start_time, getdate())
  11316.     if @num_milliseconds <> 0
  11317.         select @num_seconds = @num_milliseconds*1.0/1000
  11318.     else 
  11319.         select @num_seconds = 0
  11320.  
  11321.     select @total_rows = @num_snapshot_rows + @num_logreader_rows + 
  11322.         @num_distribution_rows +  @num_merge_rows + @num_replerror_rows
  11323.  
  11324.     if @num_seconds <> 0 
  11325.         select @rate = @total_rows/@num_seconds
  11326.     else
  11327.         select @rate = @total_rows
  11328.  
  11329.     select @seconds_str = CONVERT(nchar(10), @num_seconds)
  11330.  
  11331.     RAISERROR(14108, 10, -1, @num_merge_rows, 'MSmerge_history')
  11332.     RAISERROR(14108, 10, -1, @num_snapshot_rows, 'MSsnapshot_history')
  11333.     RAISERROR(14108, 10, -1, @num_logreader_rows, 'MSlogreader_history')
  11334.     RAISERROR(14108, 10, -1, @num_distribution_rows, 'MSdistribution_history')
  11335.     RAISERROR(14108, 10, -1, @num_replerror_rows, 'MSrepl_errors')
  11336.     RAISERROR(14149, 10, -1, @total_rows, @seconds_str, @rate)
  11337.     
  11338.     return 0
  11339.  
  11340. FAIL:
  11341.     -- Raise the Agent Failure error
  11342.     set @agent_type  = formatmessage(20544)
  11343.     SELECT @agent_name = db_name() + @agent_type
  11344.     set @message  = formatmessage(20553)
  11345.     exec dbo.sp_MSrepl_raiserror @agent_type, @agent_name, 5, @message
  11346.  
  11347.     return (1)
  11348.  
  11349. GO
  11350.  
  11351. raiserror(15339,-1,-1,'sp_MSget_repl_version')
  11352. GO
  11353. CREATE PROCEDURE sp_MSget_repl_version
  11354. @major_version int = 0 OUTPUT,
  11355. @minor_version int = 0 OUTPUT,
  11356. @revision int = 0 OUTPUT
  11357.  
  11358. as
  11359. SELECT @major_version = major_version,
  11360.        @minor_version = minor_version,
  11361.        @revision = revision FROM MSrepl_version
  11362. GO
  11363.  
  11364. raiserror(15339,-1,-1,'sp_MSenum_subscriptions')
  11365. GO
  11366. create procedure sp_MSenum_subscriptions
  11367. @publisher sysname,
  11368. @publisher_db sysname,
  11369. @publication sysname
  11370. as
  11371.  
  11372.     declare @subscriber sysname
  11373.     declare @subscriber_id smallint
  11374.     declare @subscriber_db sysname
  11375.     declare @subscriber_name sysname
  11376.     declare @type int
  11377.     declare @status int
  11378.     declare @distribution_agent nvarchar(100)
  11379.     declare @publisher_id smallint
  11380.     declare @independent_agent bit
  11381.  
  11382.     declare @start_time nvarchar(24)
  11383.     declare @time nvarchar(24)
  11384.     declare @duration int
  11385.     declare @comments nvarchar(255)
  11386.     declare @delivery_time int
  11387.     declare @delivered_transactions int
  11388.     declare @delivered_commands int
  11389.     declare @average_commands int
  11390.     declare @delivery_rate int
  11391.     declare @delivery_latency int
  11392.     declare @error_id int
  11393.     declare @publication_id int
  11394.     declare @job_id binary(16)
  11395.     declare @agent_id int
  11396.     declare @local_job bit
  11397.     declare @profile_id int
  11398.     declare @current_time datetime
  11399.     declare @last_timestamp binary(8)
  11400.  
  11401.     set nocount on
  11402.  
  11403.     set @current_time = getdate()
  11404.  
  11405.     select @publisher_id = srvid from master..sysservers where
  11406.        UPPER(srvname) = UPPER(@publisher)
  11407.  
  11408.     select @publication_id = publication_id from MSpublications  where 
  11409.             publisher_id = @publisher_id and
  11410.             publisher_db = @publisher_db and
  11411.             publication = @publication and
  11412.             (publication_type = 0 or publication_type = 1)
  11413.  
  11414.     create table #subscriptions (subscriber sysname NOT NULL,  status int NOT NULL, 
  11415.         subscriber_db sysname NOT NULL,
  11416.         type tinyint NOT NULL, distribution_agent nvarchar(100) NOT NULL, last_action nvarchar(255) NULL, 
  11417.         action_time nvarchar(24) NULL, start_time nvarchar(24) NULL, duration int NULL, 
  11418.         delivery_rate float NULL,
  11419.         delivery_latency int NULL, delivered_transactions int NULL, 
  11420.         delivered_commands int NULL,
  11421.         delivery_time int NULL, average_commands int NULL, 
  11422.         error_id int NULL, 
  11423.         job_id binary(16) NULL, local_job bit NULL, profile_id int NOT NULL,
  11424.         agent_id int NOT NULL, last_timestamp binary(8) NOT NULL)
  11425.     
  11426.     -- This is to force all queries to return rows ordered by job_id
  11427.     -- Note: There might be dist agents left for cleaning up sub, in this case
  11428.     -- they are not in sub table and we don't want to show them
  11429.     create unique clustered index ucsubscriptions ON #subscriptions (agent_id)
  11430.     declare hC CURSOR LOCAL FAST_FORWARD FOR select id, name, subscriber_id, subscriber_db,
  11431.         job_id, local_job, subscription_type, profile_id, subscriber_name
  11432.         from MSdistribution_agents a
  11433.         where exists (select * from MSsubscriptions s where
  11434.             (a.id = s.agent_id or a.anonymous_agent_id = s.agent_id) and
  11435.             s.publisher_id = @publisher_id and
  11436.             s.publisher_db = @publisher_db and
  11437.             -- For 6.x publisher, we don't know the association between the publication
  11438.             -- and subscriptions. Show every dist agent under each publication.
  11439.             (s.publication_id = @publication_id or s.publication_id = 0 ) and
  11440.             (a.subscriber_id >= 0  or a.subscriber_id is NULL))
  11441.         for read only
  11442.  
  11443.     -- declare hC CURSOR LOCAL FAST_FORWARD FOR select a.id, a.name, a.subscriber_id, ms.subscriber_db,
  11444.     --  a.job_id, a.local_job, ms.subscription_type, a.profile_id, a.subscriber_name
  11445.     --    from MSdistribution_agents a, master..sysservers s, MSsubscriptions ms
  11446.     --    where
  11447.     --    a.publisher_id = @publisher_id and
  11448.     --    a.publisher_db = @publisher_db and
  11449.     --  (a.publication = @publication or a.publication = 'ALL') and
  11450.     --  a.subscriber_id >= 0 and
  11451.     --  ms.publisher_db = @publisher_db and
  11452.     --  ms.publication_id = @publication_id and
  11453.     --  ms.subscriber_id = a.subscriber_id and
  11454.     --  ms.subscriber_db = a.subscriber_db and
  11455.     --  s.srvid = ms.subscriber_id
  11456.     --  for read only
  11457.  
  11458.     open hC
  11459.     fetch hC into  @agent_id, @distribution_agent, @subscriber_id, @subscriber_db,
  11460.         @job_id, @local_job, @type, @profile_id, @subscriber_name
  11461.     while (@@fetch_status <> -1)
  11462.     begin
  11463.         /* Stuff in the values for no history case */
  11464.         select @status = 0, 
  11465.             @start_time = NULL,
  11466.             @time = NULL, @duration = NULL, @comments = NULL,
  11467.             @delivery_time = NULL, @delivered_transactions = NULL,
  11468.             @delivered_commands = NULL, @average_commands = NULL,
  11469.             @delivery_rate = NULL, @delivery_latency = NULL,
  11470.             @error_id = NULL,
  11471.             @last_timestamp = 0x00000000
  11472.  
  11473.         -- Get the status of the agent
  11474.         select @status = runstatus, 
  11475.             @start_time = convert(nvarchar(12), start_time, 112) +
  11476.                           substring(convert(nvarchar(24), start_time, 121), 11, 13),
  11477.             @time = convert(nvarchar(12), time, 112) +
  11478.                     substring(convert(nvarchar(24), time, 121), 11, 13), 
  11479.             @duration = DATEDIFF(second, start_time, @current_time), 
  11480.             @comments = comments,
  11481.             @delivery_time = 0, @delivered_transactions = delivered_transactions,
  11482.             @delivered_commands = delivered_commands, @average_commands = average_commands,
  11483.             -- Note: return average rate here !!! delivery_rate column is current rate
  11484.             @delivery_rate = delivery_rate,
  11485.             @delivery_latency = delivery_latency,
  11486.             @error_id = error_id, @last_timestamp = timestamp
  11487.             from MSdistribution_history
  11488.             where
  11489.                 agent_id = @agent_id and
  11490.                 timestamp = (select max(timestamp) from MSdistribution_history 
  11491.                     where 
  11492.                     agent_id = @agent_id)
  11493.  
  11494.         -- For anonymous subscriptions, @subscriber_name is not NULL
  11495.          if @subscriber_name is NULL
  11496.                 select @subscriber = srvname from master..sysservers where srvid=@subscriber_id
  11497.             else 
  11498.                 begin
  11499.                     select @subscriber = @subscriber_name
  11500.                     select @subscriber_db = @subscriber_db + '-' + convert(nvarchar(4), @agent_id)
  11501.                 end
  11502.  
  11503.         insert into #subscriptions values ( @subscriber, @status, @subscriber_db,
  11504.             @type, @distribution_agent, @comments, @time, @start_time, @duration,
  11505.             @delivery_rate, @delivery_latency, @delivered_transactions, 
  11506.             @delivered_commands,  @delivery_time, @average_commands,
  11507.             @error_id, @job_id, @local_job, @profile_id, @agent_id, @last_timestamp)
  11508.  
  11509.         fetch hC into  @agent_id, @distribution_agent, @subscriber_id, @subscriber_db,
  11510.             @job_id, @local_job, @type, @profile_id, @subscriber_name
  11511.       end
  11512.  
  11513.     select * from #subscriptions order by job_id asc 
  11514.  
  11515.     drop table #subscriptions
  11516.     close hC
  11517.     deallocate hC
  11518. go
  11519.  
  11520.  
  11521. raiserror(15339,-1,-1,'sp_MSenum_snapshot')
  11522. go
  11523. create procedure sp_MSenum_snapshot
  11524. @name nvarchar(100) = '%',
  11525. @show_distdb bit = 0
  11526. as
  11527.     set nocount on
  11528.  
  11529.     declare @publisher sysname
  11530.     declare @publisher_db sysname
  11531.     declare @publication sysname
  11532.     declare @publication_id int
  11533.     declare @snapshot_agent nvarchar(100)
  11534.     declare @status int
  11535.     declare @start_time nvarchar(24)
  11536.     declare @time nvarchar(24)
  11537.     declare @duration int
  11538.     declare @comments nvarchar(255)
  11539.     declare @delivered_transactions int
  11540.     declare @delivered_commands int
  11541.     declare @delivery_rate int
  11542.     declare @publisher_id smallint
  11543.     declare @error_id int
  11544.     declare @job_id binary(16)
  11545.     declare @local_job bit
  11546.     declare @profile_id int
  11547.     declare @agent_id int
  11548.     declare @current_time datetime
  11549.     declare @last_timestamp binary(8)
  11550.  
  11551.     set @current_time = getdate()
  11552.  
  11553.     create table #snapshot_agent (name nvarchar(100) NOT NULL, status int NOT NULL,
  11554.         publisher sysname NOT NULL, publisher_db sysname NOT NULL, publication sysname NOT NULL,
  11555.         start_time nvarchar(24)  NULL, time nvarchar(24)  NULL, duration int NULL, 
  11556.         comments nvarchar(255) NULL, delivered_transactions int NULL, delivered_commands int NULL,
  11557.         delivery_rate float  NULL, error_id int NULL, job_id binary(16) NULL, local_job bit NOT NULL,
  11558.         profile_id int NOT NULL, agent_id int NOT NULL, last_timestamp binary(8) NOT NULL)
  11559.   
  11560.  
  11561.     declare hC  CURSOR LOCAL FAST_FORWARD FOR
  11562.          select srvname, sa.publisher_db, sa.publication, sa.name, sa.publisher_id,
  11563.             sa.local_job, sa.job_id, sa.profile_id, sa.id
  11564.             from
  11565.             MSsnapshot_agents sa, master..sysservers
  11566.             where 
  11567.             name LIKE @name and
  11568.             srvid = sa.publisher_id
  11569.         for read only
  11570.  
  11571.     OPEN hC
  11572.     FETCH hC INTO @publisher, @publisher_db, @publication, @snapshot_agent, @publisher_id,
  11573.         @local_job, @job_id, @profile_id, @agent_id
  11574.     WHILE (@@fetch_status <> -1)
  11575.         begin
  11576.      
  11577.         -- Get the publication id
  11578.         select @publication_id = isnull(publication_id, 0) from MSpublications where
  11579.             publisher_id = @publisher_id and
  11580.             publisher_db = @publisher_db and
  11581.             publication = @publication
  11582.             
  11583.         -- Stuff in the values for no history case 
  11584.         select @status = 0, 
  11585.             @start_time = NULL,
  11586.             @time = NULL, @duration = NULL, @comments = NULL,
  11587.             @delivered_commands = NULL, 
  11588.             @delivery_rate = NULL, 
  11589.             @error_id = NULL,
  11590.             @last_timestamp = 0x00000000        
  11591.        
  11592.         -- Get the status of the agent
  11593.         select @status = runstatus, 
  11594.             @start_time = convert(nvarchar(12), start_time, 112) + 
  11595.                           substring(convert(nvarchar(24), start_time, 121), 11, 13), 
  11596.             @time = convert(nvarchar(12), time, 112) + 
  11597.                     substring(convert(nvarchar(24), time, 121), 11, 13), 
  11598.             @duration = DATEDIFF(second, start_time, @current_time), 
  11599.             @comments = comments,
  11600.             @delivered_transactions = delivered_transactions,
  11601.             @delivered_commands = delivered_commands,
  11602.             @delivery_rate = delivery_rate, 
  11603.             @error_id = error_id, 
  11604.             @last_timestamp = timestamp
  11605.             from MSsnapshot_history
  11606.             where
  11607.             agent_id = @agent_id and
  11608.             timestamp = (select top 1 timestamp from MSsnapshot_history where           
  11609.                 agent_id = @agent_id
  11610.                 order by timestamp DESC) 
  11611.     
  11612.         insert into #snapshot_agent values (@snapshot_agent, @status, @publisher,
  11613.             @publisher_db, @publication, @start_time, @time, @duration, @comments,
  11614.             @delivered_transactions, @delivered_commands, @delivery_rate, @error_id, @job_id, 
  11615.             @local_job, @profile_id, @agent_id, @last_timestamp)
  11616.  
  11617.         FETCH hC INTO @publisher, @publisher_db, @publication, @snapshot_agent,
  11618.             @publisher_id, @local_job, @job_id, @profile_id, @agent_id
  11619.         end
  11620.  
  11621.     if @show_distdb = 0
  11622.         select * from #snapshot_agent 
  11623.     else 
  11624.         select 'dbname' = DB_NAME(), * from #snapshot_agent
  11625.  
  11626.     drop table #snapshot_agent
  11627.     close hC
  11628.     deallocate hC
  11629.  
  11630. GO
  11631.  
  11632. raiserror(15339,-1,-1,'sp_MSenum_snapshot_s')
  11633. go
  11634. create procedure sp_MSenum_snapshot_s
  11635. @name nvarchar(100),
  11636. @hours int = 0, /* @hours < 0 will return TOP 100 */
  11637. @session_type int = 1 /* Return all sessions */
  11638. as
  11639.     set nocount on
  11640.  
  11641.     declare @succeed int
  11642.     declare @retry int
  11643.     declare @failure int
  11644.     declare @min_time datetime
  11645.     declare @independent_agent bit
  11646.     declare @publisher_id smallint
  11647.     declare @publisher_db sysname
  11648.     declare @publication sysname
  11649.     declare @agent_id    int
  11650.     
  11651.     /* 
  11652.     ** Status const defined in sqlrepl.h 
  11653.     */
  11654.     
  11655.     select @succeed = 2
  11656.     select @retry = 5
  11657.     select @failure = 6
  11658.  
  11659.     SELECT @publisher_id = publisher_id, @publisher_db = publisher_db, 
  11660.         @publication = publication, @agent_id=id
  11661.         from
  11662.         MSsnapshot_agents 
  11663.         where 
  11664.         name = @name 
  11665.  
  11666.     /* Get date starting point */
  11667.     IF @hours < 0
  11668.     BEGIN
  11669.         select top 100 sh1.runstatus, 
  11670.             'start_time' = convert(nvarchar(12), sh1.start_time, 112) + 
  11671.                            substring(convert(nvarchar(24), sh1.start_time, 121), 11, 13), 
  11672.             'time' = convert(nvarchar(12), sh1.time, 112) + 
  11673.                      substring(convert(nvarchar(24), sh1.time, 121), 11, 13), 
  11674.             sh1.comments, sh1.duration,
  11675.             sh1.delivery_rate, sh1.delivered_commands,
  11676.             'action_count' = (select count(*) from MSsnapshot_history where
  11677.                     start_time = sh1.start_time and agent_id=@agent_id),
  11678.             sh1.error_id
  11679.             from MSsnapshot_history sh1, MSsnapshot_agents sa
  11680.             where
  11681.             sa.publisher_id = @publisher_id and
  11682.             sa.publisher_db = @publisher_db and
  11683.             sa.publication = @publication and
  11684.             sh1.agent_id = sa.id and
  11685.             ((@session_type = 1 and 
  11686.                 (sh1.runstatus = @succeed or
  11687.                     sh1.runstatus = @retry or
  11688.                     sh1.timestamp = (select max(timestamp) from MSsnapshot_history sh2 where
  11689.                         sh2.agent_id = sh1.agent_id))) or
  11690.             sh1.runstatus = @failure)
  11691.             order by sh1.timestamp desc
  11692.     END
  11693.     ELSE
  11694.     BEGIN
  11695.         IF @hours = 0
  11696.         BEGIN
  11697.             select @min_time = NULL
  11698.         END
  11699.         ELSE
  11700.         BEGIN
  11701.             select @min_time = dateadd(hour, -@hours, getdate())
  11702.         END
  11703.         select sh1.runstatus, 
  11704.             'start_time' = convert(nvarchar(12), sh1.start_time, 112) + 
  11705.                            substring(convert(nvarchar(24), sh1.start_time, 121), 11, 13), 
  11706.             'time' = convert(nvarchar(12), sh1.time, 112) + 
  11707.                      substring(convert(nvarchar(24), sh1.time, 121), 11, 13), 
  11708.             sh1.comments, sh1.duration,
  11709.             sh1.delivery_rate, sh1.delivered_commands,
  11710.             'action_count' = (select count(*) from MSsnapshot_history where
  11711.                     start_time = sh1.start_time and agent_id=@agent_id),    
  11712.             sh1.error_id
  11713.             from MSsnapshot_history sh1, MSsnapshot_agents sa
  11714.             where
  11715.             sa.publisher_id = @publisher_id and
  11716.             sa.publisher_db = @publisher_db and
  11717.             sa.publication = @publication and
  11718.             sh1.agent_id = sa.id and
  11719.             ((@session_type = 1 and 
  11720.                 (sh1.runstatus = @succeed or
  11721.                     sh1.runstatus = @retry or
  11722.                     sh1.timestamp = (select max(timestamp) from MSsnapshot_history sh2 where
  11723.                         sh2.agent_id = sh1.agent_id))) or
  11724.             sh1.runstatus = @failure) and
  11725.             (sh1.time >= @min_time OR @min_time IS NULL)
  11726.             order by sh1.timestamp desc
  11727.     END
  11728.  
  11729. GO
  11730.  
  11731.  
  11732. raiserror(15339,-1,-1,'sp_MSenum_snapshot_sd')
  11733. go
  11734. create procedure sp_MSenum_snapshot_sd
  11735. @name nvarchar(100),
  11736. @time datetime = NULL
  11737. as
  11738.     set nocount on
  11739.  
  11740.     declare @start_time datetime
  11741.     declare @time_up datetime
  11742.     declare @publisher_id smallint
  11743.     declare @publisher_db sysname
  11744.     declare @publication sysname
  11745.  
  11746.     IF @time IS NULL
  11747.         select @time = GETDATE()
  11748.     /* 
  11749.     ** If @name is given, get its publisher and subscriber pair
  11750.     ** Note: param will be overwritten
  11751.     ** If @name is NOT given, use provided param.
  11752.     */
  11753.     SELECT @publisher_id = pub.publisher_id, @publisher_db = pub.publisher_db, 
  11754.         @publication = pub.publication
  11755.         from
  11756.         MSsnapshot_agents agent, MSpublications pub
  11757.         where 
  11758.         name LIKE @name and
  11759.         agent.publisher_id = pub.publisher_id and
  11760.         agent.publication = pub.publication and
  11761.         agent.publisher_db = pub.publisher_db
  11762.     
  11763.     /*
  11764.     ** Minute-approximate @time can be used.
  11765.     **
  11766.     ** Note: The select only return datetime data with minute precisio
  11767.     */
  11768.     IF  DATEPART(second, @time) = 0 AND
  11769.         DATEPART(millisecond, @time) = 0
  11770.     BEGIN
  11771.         SELECT @time_up = DATEADD(second, +59, @time)
  11772.         SELECT @time_up = DATEADD(millisecond, +999, @time)
  11773.     END
  11774.     ELSE
  11775.         SELECT @time_up = @time
  11776.         
  11777.  
  11778.     select top 1 @start_time = sh.start_time            
  11779.          from MSsnapshot_history sh, MSsnapshot_agents sa
  11780.         where
  11781.         sa.publisher_id = @publisher_id and
  11782.         sa.publisher_db = @publisher_db and
  11783.         sa.publication  = @publication and
  11784.         sh.agent_id = sa.id and
  11785.         sh.time <= @time_up 
  11786.         order by sh.timestamp DESC
  11787.  
  11788.     select sh.runstatus, 
  11789.         'time' = convert(nvarchar(12), sh.time, 112) + 
  11790.                  substring(convert(nvarchar(24), sh.time, 121), 11, 13), 
  11791.         sh.comments, 
  11792.         sh.duration, 
  11793.         sh.delivery_rate, 
  11794.         sh.delivered_commands,
  11795.         sa.name, 
  11796.         sh.error_id         
  11797.         from MSsnapshot_history sh, MSsnapshot_agents sa
  11798.         where
  11799.         sa.publisher_id = @publisher_id and
  11800.         sa.publisher_db = @publisher_db and
  11801.         sa.publication = @publication and 
  11802.         sh.agent_id = sa.id and
  11803.         sh.start_time = @start_time 
  11804.         order by sh.timestamp desc
  11805. GO
  11806.  
  11807.  
  11808. raiserror(15339,-1,-1,'sp_MSenum_logreader')
  11809. go
  11810. create procedure sp_MSenum_logreader
  11811. @name nvarchar(100) = '%',
  11812. @show_distdb bit = 0
  11813. as
  11814.     set nocount on
  11815.  
  11816.     declare @publisher sysname
  11817.     declare @publisher_db sysname
  11818.     declare @logreader_agent nvarchar(100)
  11819.     declare @status int
  11820.     declare @start_time nvarchar(24)
  11821.     declare @time nvarchar(24)
  11822.     declare @duration int
  11823.     declare @comments nvarchar(255)
  11824.     declare @delivery_time int
  11825.     declare @delivered_transactions int
  11826.     declare @delivered_commands int
  11827.     declare @average_commands int
  11828.     declare @delivery_rate int
  11829.     declare @delivery_latency int
  11830.     declare @error_id int
  11831.     declare @job_id binary(16)
  11832.     declare @local_job bit
  11833.     declare @profile_id int
  11834.     declare @agent_id int
  11835.     declare @current_time datetime
  11836.     declare @last_timestamp binary(8)
  11837.  
  11838.     set @current_time = getdate()
  11839.  
  11840.     create table #logreader_agent (name nvarchar(100) NOT NULL, status int NOT NULL,
  11841.         publisher sysname NOT NULL, publisher_db sysname NOT NULL,
  11842.         start_time nvarchar(24)  NULL, time nvarchar(24)  NULL, duration int  NULL, 
  11843.         comments nvarchar(255) NULL, delivery_time int NULL, 
  11844.         delivered_transactions int  NULL, delivered_commands int NULL, 
  11845.         average_commands int  NULL, delivery_rate int NULL, 
  11846.         delivery_latency int NULL, error_id int NULL, job_id binary(16) NULL,
  11847.         local_job bit NULL, profile_id int NOT NULL, agent_id int NOT NULL, last_timestamp binary(8) NOT NULL)  
  11848.    
  11849.     declare hC  CURSOR LOCAL FAST_FORWARD FOR
  11850.          select server.srvname, agent.publisher_db, name, 
  11851.             local_job, job_id, agent.profile_id, agent.id
  11852.             from
  11853.             MSlogreader_agents agent, master..sysservers server
  11854.             where 
  11855.             name LIKE @name and
  11856.             server.srvid = agent.publisher_id
  11857.         
  11858.         for read only
  11859.  
  11860.     OPEN hC
  11861.     FETCH hC INTO @publisher, @publisher_db, @logreader_agent, 
  11862.         @local_job, @job_id, @profile_id, @agent_id
  11863.     WHILE (@@fetch_status <> -1)
  11864.         begin
  11865.  
  11866.         /* Stuff in the values for no history case */
  11867.         select @status = 0, 
  11868.             @start_time = NULL,
  11869.             @time = NULL, @duration = NULL, @comments = NULL,
  11870.             @delivery_time = NULL, @delivered_transactions = NULL,
  11871.             @delivered_commands = NULL, @average_commands = NULL,
  11872.             @delivery_rate = NULL, @delivery_latency = NULL,
  11873.             @error_id = NULL,
  11874.             @last_timestamp = 0x00000000
  11875.  
  11876.         -- Get the status of the agent
  11877.         select @status = lh.runstatus, 
  11878.             @start_time = convert(nvarchar(12), start_time, 112) +
  11879.                           substring(convert(nvarchar(24), start_time, 121), 11, 13),
  11880.             @time = convert(nvarchar(12), time, 112) +
  11881.                     substring(convert(nvarchar(24),  time, 121), 11, 13), 
  11882.             @duration = DATEDIFF(second, start_time, @current_time), 
  11883.             @comments = comments,
  11884.             @delivery_time = delivery_time, @delivered_transactions = delivered_transactions,
  11885.             @delivered_commands = delivered_commands, @average_commands = average_commands,
  11886.             @delivery_rate = delivery_rate, @delivery_latency = delivery_latency,
  11887.             @error_id = error_id, @last_timestamp = timestamp
  11888.             from MSlogreader_history lh
  11889.             where
  11890.             lh.agent_id = @agent_id and
  11891.             lh.timestamp = (select max(timestamp) from MSlogreader_history
  11892.                 where
  11893.                 agent_id = lh.agent_id)
  11894.  
  11895.         insert into #logreader_agent values (@logreader_agent, @status, @publisher,
  11896.             @publisher_db, @start_time, @time, @duration, @comments,
  11897.             @delivery_time, @delivered_transactions, @delivered_commands, @average_commands,
  11898.             @delivery_rate, @delivery_latency, @error_id, @job_id, @local_job,
  11899.             @profile_id, @agent_id, @last_timestamp)
  11900.  
  11901.         FETCH hC INTO @publisher, @publisher_db, @logreader_agent, 
  11902.             @local_job, @job_id, @profile_id, @agent_id
  11903.         end
  11904.  
  11905.     if @show_distdb = 0
  11906.         select * from #logreader_agent 
  11907.     else 
  11908.         select 'dbname' = DB_NAME(), * from #logreader_agent
  11909.  
  11910.     drop table #logreader_agent
  11911.     close hC
  11912.     deallocate hC
  11913. GO
  11914.  
  11915.  
  11916. raiserror(15339,-1,-1,'sp_MSenum_logreader_s')
  11917. go
  11918.  
  11919. create procedure sp_MSenum_logreader_s
  11920. @name nvarchar(100),
  11921. @hours int = 0, /* @hours < 0 will return TOP 100 */
  11922. @session_type int = 1 /* Return all sessions */
  11923. as
  11924.     set nocount on
  11925.  
  11926.     declare @succeed int
  11927.     declare @retry int
  11928.     declare @failure int      
  11929.     declare @agent_id    int
  11930.     declare @min_time datetime
  11931.  
  11932.     if @session_type  not in (1,2)
  11933.     begin
  11934.         return(1)
  11935.     end 
  11936.  
  11937.     select @agent_id  = (select top 1 id from MSlogreader_agents where name = @name) 
  11938.  
  11939.     /* 
  11940.     ** Status const defined in sqlrepl.h 
  11941.     */
  11942.     select @succeed = 2
  11943.     select @retry = 5
  11944.     select @failure = 6
  11945.  
  11946.     /* Get date starting point */
  11947.     IF @hours < 0
  11948.     BEGIN
  11949.         select  top 100 runstatus, 
  11950.                 'start_time' = convert(nvarchar(12), start_time, 112) + 
  11951.                                substring(convert(nvarchar(24), start_time, 121), 11, 13), 
  11952.                 'time' = convert(nvarchar(12), time, 112) +
  11953.                          substring(convert(nvarchar(24), time, 121), 11, 13), 
  11954.                 comments, duration, delivery_rate, delivery_latency,
  11955.             delivery_time,  delivered_transactions, delivered_commands, average_commands, 
  11956.             'action_count' = (select count(*) from MSlogreader_history where
  11957.                 start_time = rh.start_time and agent_id=@agent_id),
  11958.             error_id
  11959.             from MSlogreader_history rh
  11960.             where
  11961.             rh.agent_id = (select top 1 id from MSlogreader_agents where name = @name) and
  11962.             ((@session_type = 1 and (runstatus = @succeed or
  11963.                 runstatus = @retry or
  11964.                 timestamp = (select max(timestamp) from MSlogreader_history rh2 where
  11965.                     rh2.agent_id = rh.agent_id))) or
  11966.             runstatus = @failure) 
  11967.             order by timestamp desc
  11968.     END
  11969.     ELSE
  11970.     BEGIN
  11971.         IF @hours = 0
  11972.         BEGIN
  11973.             select @min_time = NULL
  11974.         END
  11975.         ELSE
  11976.         BEGIN
  11977.             select @min_time = dateadd(hour, -@hours, getdate())
  11978.         END
  11979.  
  11980.         select  runstatus, 
  11981.                 'start_time' = convert(nvarchar(12), start_time, 112) + 
  11982.                                substring(convert(nvarchar(24), start_time, 121), 11, 13), 
  11983.                 'time' = convert(nvarchar(12), time, 112) +
  11984.                          substring(convert(nvarchar(24), time, 121), 11, 13), 
  11985.                 comments, duration, delivery_rate, delivery_latency,
  11986.             delivery_time,  delivered_transactions, delivered_commands, average_commands, 
  11987.             'action_count' = (select count(*) from MSlogreader_history where
  11988.                 start_time = rh.start_time and agent_id=@agent_id),
  11989.             error_id
  11990.             from MSlogreader_history rh
  11991.             where
  11992.             rh.agent_id = (select top 1 id from MSlogreader_agents where name = @name) and
  11993.             ((@session_type = 1 and (runstatus = @succeed or
  11994.                 runstatus = @retry or
  11995.                 timestamp = (select max(timestamp) from MSlogreader_history rh2 where
  11996.                     rh2.agent_id = rh.agent_id))) or
  11997.             runstatus = @failure) and
  11998.             (time >= @min_time OR @min_time IS NULL)
  11999.             order by timestamp desc
  12000.     END
  12001.  
  12002. GO
  12003.  
  12004. raiserror(15339,-1,-1,'sp_MSenum_logreader_sd')
  12005. go
  12006.  
  12007. create procedure sp_MSenum_logreader_sd
  12008. @name nvarchar(100),
  12009. @time datetime = NULL
  12010. as
  12011.     set nocount on
  12012.  
  12013.     declare @start_time datetime
  12014.     declare @time_up datetime
  12015.  
  12016.     IF @time IS NULL
  12017.         select @time = GETDATE()
  12018.     /*
  12019.     ** Minute-approximate @time can be used.
  12020.     ** Note: The select only return datetime data with minute precision
  12021.     */
  12022.     IF  DATEPART(second, @time) = 0 AND
  12023.         DATEPART(millisecond, @time) = 0
  12024.     BEGIN
  12025.         SELECT @time_up = DATEADD(second, +59, @time)
  12026.         SELECT @time_up = DATEADD(millisecond, +999, @time)
  12027.     END
  12028.     ELSE
  12029.         SELECT @time_up = @time
  12030.         
  12031.  
  12032.     select  top 1 @start_time = start_time          
  12033.          from MSlogreader_history rh
  12034.         where
  12035.         rh.agent_id = (select top 1 id from MSlogreader_agents where name = @name) and
  12036.         time <= @time_up 
  12037.         order by timestamp DESC
  12038.  
  12039.     select  runstatus, 
  12040.             'time' = convert(nvarchar(12), time, 112) +
  12041.                      substring(convert(nvarchar(24), time, 121), 11, 13), 
  12042.             comments,duration, delivery_rate, delivery_latency,
  12043.         delivery_time,  delivered_transactions, delivered_commands, average_commands, 
  12044.         error_id        
  12045.         from MSlogreader_history rh
  12046.         where
  12047.         rh.agent_id = (select top 1 id from MSlogreader_agents where name = @name) and
  12048.         start_time = @start_time 
  12049.         order by timestamp desc
  12050. GO
  12051.  
  12052.  
  12053. raiserror(15339,-1,-1,'sp_MSenum_distribution')
  12054. go
  12055. create procedure sp_MSenum_distribution
  12056. @name nvarchar(100) = '%',
  12057. @show_distdb bit = 0
  12058. as
  12059.     set nocount on
  12060.  
  12061.     declare @publisher sysname
  12062.     declare @publisher_id smallint
  12063.     declare @publisher_db sysname
  12064.     declare @publication sysname
  12065.     declare @subscriber sysname
  12066.     declare @subscriber_id smallint
  12067.     declare @subscriber_db sysname
  12068.     declare @subscriber_name sysname
  12069.     declare @distribution_agent nvarchar(100)
  12070.     declare @status int
  12071.     declare @start_time nvarchar(24)
  12072.     declare @time nvarchar(24)
  12073.     declare @duration int
  12074.     declare @comments nvarchar(255)
  12075.     declare @delivery_time int
  12076.     declare @delivered_transactions int
  12077.     declare @delivered_commands int
  12078.     declare @average_commands int
  12079.     declare @delivery_rate int
  12080.     declare @delivery_latency int   
  12081.     declare @subscription_type int
  12082.     declare @error_id int
  12083.     declare @job_id binary(16)
  12084.     declare @local_job bit
  12085.     declare @agent_id int
  12086.     declare @profile_id int
  12087.     declare @current_time datetime
  12088.     declare @last_timestamp binary(8)
  12089.  
  12090.  
  12091.     set @current_time = getdate()
  12092.  
  12093.     create table #distribution_agent (name nvarchar(100) NOT NULL, status int NOT NULL,
  12094.         publisher sysname NOT NULL, publisher_db sysname NOT NULL, publication sysname NULL,
  12095.         subscriber sysname NULL, subscriber_db sysname NULL,subscription_type int NULL, 
  12096.         start_time nvarchar(24) NULL, time nvarchar(24) NULL, duration int NULL, 
  12097.         comments nvarchar(255) NULL, delivery_time int NULL, 
  12098.         delivered_transactions int NULL, delivered_commands int NULL, 
  12099.         average_commands int NULL, delivery_rate int NULL, delivery_latency int NULL,
  12100.         error_id int NULL, job_id binary(16) NULL, local_job bit NOT NULL,
  12101.         profile_id int NOT NULL, agent_id int NOT NULL, last_timestamp binary(8) NOT NULL)
  12102.  
  12103.     /* excluding virtual subscriptions */
  12104.     declare hC CURSOR LOCAL FAST_FORWARD FOR
  12105.         select id, name, publisher_id, publisher_db, publication, 
  12106.             subscriber_id, subscriber_db, subscription_type, local_job, job_id,
  12107.             profile_id, subscriber_name
  12108.             from
  12109.             MSdistribution_agents 
  12110.             where 
  12111.             name LIKE @name and subscriber_id is NULL or subscriber_id>=0  --No virtual subscription wanted
  12112.         for read only
  12113.  
  12114.  
  12115.     OPEN hC
  12116.     FETCH hC INTO @agent_id, @distribution_agent, @publisher_id, @publisher_db, @publication,
  12117.         @subscriber_id, @subscriber_db, @subscription_type, @local_job, @job_id, @profile_id, @subscriber_name
  12118.     WHILE (@@fetch_status <> -1)
  12119.         begin
  12120.         
  12121.         /* Stuff in the values for no history case */
  12122.         select @status = 0, 
  12123.             @start_time = NULL,
  12124.             @time = NULL, @duration = NULL, @comments = NULL,
  12125.             @delivery_time = NULL, @delivered_transactions = NULL,
  12126.             @delivered_commands = NULL, @average_commands = NULL,
  12127.             @delivery_rate = NULL, @delivery_latency = NULL,
  12128.             @error_id = NULL,
  12129.             @last_timestamp = 0x00000000
  12130.  
  12131.         select @status = isnull(runstatus, 0),
  12132.             @start_time = convert(nvarchar(12), start_time, 112) +
  12133.                           substring(convert(nvarchar(24), start_time, 121), 11, 13),
  12134.             @time = convert(nvarchar(12), time, 112) +
  12135.                     substring(convert(nvarchar(24), time, 121), 11, 13), 
  12136.             @duration = DATEDIFF(second, start_time, @current_time), 
  12137.             @comments = comments,
  12138.             @delivery_time = 0, @delivered_transactions = delivered_transactions,
  12139.             @delivered_commands = delivered_commands, @average_commands = average_commands,
  12140.             @delivery_rate = delivery_rate,
  12141.             @delivery_latency = delivery_latency,
  12142.             @error_id = error_id, @last_timestamp = timestamp   
  12143.             from MSdistribution_history
  12144.             where
  12145.             agent_id = @agent_id and
  12146.             timestamp = (select max(timestamp) from MSdistribution_history 
  12147.                 where agent_id = @agent_id)
  12148.             
  12149.             select @publisher = srvname from master..sysservers where srvid = @publisher_id
  12150.         IF @subscriber_name is NULL
  12151.                 select @subscriber = srvname from master..sysservers where srvid=@subscriber_id 
  12152.         ELSE 
  12153.             begin
  12154.                 select @subscription_type = 2
  12155.                 select @subscriber = @subscriber_name
  12156.                 select @subscriber_db = @subscriber_db + '-' + convert(nvarchar(4), @agent_id)
  12157.             end
  12158.             
  12159.         insert into #distribution_agent values (@distribution_agent,
  12160.             @status, @publisher,
  12161.             @publisher_db, @publication, @subscriber, @subscriber_db, @subscription_type, 
  12162.             @start_time, @time, @duration, @comments,
  12163.             @delivery_time, @delivered_transactions, @delivered_commands, @average_commands,
  12164.             @delivery_rate, @delivery_latency, @error_id, @job_id, 
  12165.             @local_job, @profile_id, @agent_id, @last_timestamp)
  12166.  
  12167.         FETCH hC INTO @agent_id, @distribution_agent, @publisher_id, @publisher_db, @publication,
  12168.             @subscriber_id, @subscriber_db, @subscription_type, @local_job, @job_id, 
  12169.             @profile_id, @subscriber_name
  12170.         end
  12171.  
  12172.     if @show_distdb = 0
  12173.         select * from #distribution_agent 
  12174.     else 
  12175.         select 'dbname' = DB_NAME(), * from #distribution_agent
  12176.  
  12177.     drop table #distribution_agent
  12178.     close hC
  12179.     deallocate hC
  12180.  
  12181. GO
  12182.  
  12183.  
  12184. raiserror(15339,-1,-1,'sp_MSenum_distribution_s')
  12185. go
  12186. create procedure sp_MSenum_distribution_s
  12187. @name nvarchar(100), 
  12188. @hours int = 0, /* @hours < 0 will return TOP 100 */
  12189. @session_type int = 1 /* Return all sessions */
  12190. as
  12191.     set nocount on
  12192.  
  12193.     declare @succeed int
  12194.     declare @retry int
  12195.     declare @failure int
  12196.     declare @min_time datetime
  12197.     declare @agent_id int
  12198.  
  12199.     /* 
  12200.     ** Status const defined in sqlrepl.h 
  12201.     */
  12202.     select @succeed = 2
  12203.     select @retry = 5
  12204.     select @failure = 6
  12205.  
  12206.     select @agent_id = id from MSdistribution_agents where
  12207.         name = @name
  12208.  
  12209.  
  12210.     /* Get date starting point */
  12211.     IF @hours < 0
  12212.     BEGIN
  12213.         select  top 100 runstatus, 
  12214.             'start_time' = convert(nvarchar(12), start_time, 112) +
  12215.                            substring(convert(nvarchar(24), start_time, 121), 11, 13), 
  12216.             'time' = convert(nvarchar(12), time, 112) +
  12217.                      substring(convert(nvarchar(24), time, 121), 11, 13), 
  12218.             comments, duration, 
  12219.             delivery_rate,
  12220.             delivery_latency,
  12221.             0, /*delivery_time */   
  12222.             delivered_transactions, delivered_commands, average_commands, 
  12223.             'action_count' = (select count(*) from MSdistribution_history where
  12224.                 start_time = rh.start_time and agent_id=@agent_id),
  12225.             error_id
  12226.             from MSdistribution_history rh
  12227.             where
  12228.             agent_id = @agent_id and
  12229.             ((@session_type = 1 and
  12230.             (runstatus = @succeed or
  12231.             runstatus = @retry or
  12232.             timestamp = (select max(timestamp) from MSdistribution_history rh2 where
  12233.                 rh2.agent_id = @agent_id))) or 
  12234.             runstatus = @failure) 
  12235.             order by timestamp desc
  12236.     END
  12237.     ELSE
  12238.     BEGIN
  12239.         IF @hours = 0
  12240.         BEGIN
  12241.             select @min_time = NULL
  12242.         END
  12243.         ELSE
  12244.         BEGIN
  12245.             select @min_time = dateadd(hour, -@hours, getdate())
  12246.         END
  12247.  
  12248.         select  runstatus, 
  12249.             'start_time' = convert(nvarchar(12), start_time, 112) +
  12250.                            substring(convert(nvarchar(24), start_time, 121), 11, 13), 
  12251.             'time' = convert(nvarchar(12), time, 112) +
  12252.                      substring(convert(nvarchar(24), time, 121), 11, 13), 
  12253.             comments, duration, 
  12254.             delivery_rate,
  12255.             delivery_latency,
  12256.             0, /*delivery_time */   
  12257.             delivered_transactions, delivered_commands, average_commands, 
  12258.             'action_count' = (select count(*) from MSdistribution_history where
  12259.                 start_time = rh.start_time and agent_id=@agent_id),
  12260.             error_id
  12261.             from MSdistribution_history rh
  12262.             where
  12263.             agent_id = @agent_id and
  12264.             ((@session_type = 1 and
  12265.             (runstatus = @succeed or
  12266.             runstatus = @retry or
  12267.             timestamp = (select max(timestamp) from MSdistribution_history rh2 where
  12268.                 rh2.agent_id = @agent_id))) or 
  12269.             runstatus = @failure) and
  12270.             (time >= @min_time or @min_time IS NULL)
  12271.             order by timestamp desc
  12272.     END
  12273.  
  12274. GO
  12275.  
  12276.  
  12277. raiserror(15339,-1,-1,'sp_MSenum_distribution_sd')
  12278. go
  12279. create procedure sp_MSenum_distribution_sd
  12280. @name nvarchar(100),
  12281. @time datetime = NULL
  12282. as
  12283.     set nocount on
  12284.  
  12285.     declare @start_time datetime
  12286.     declare @time_up datetime
  12287.     declare @agent_id int
  12288.  
  12289.     IF @time IS NULL
  12290.         select @time = GETDATE()
  12291.     
  12292.     select @agent_id = id from MSdistribution_agents where
  12293.         name = @name
  12294.  
  12295.     /*
  12296.     ** Minute-approximate @time can be used.
  12297.     ** Note: The select only return datetime data with minute precision
  12298.     */
  12299.     IF  DATEPART(second, @time) = 0 AND
  12300.         DATEPART(millisecond, @time) = 0
  12301.     BEGIN
  12302.         SELECT @time_up = DATEADD(second, +59, @time)
  12303.         SELECT @time_up = DATEADD(millisecond, +999, @time)
  12304.     END
  12305.     ELSE
  12306.         SELECT @time_up = @time
  12307.         
  12308.  
  12309.     select top 1 @start_time = start_time           
  12310.          from MSdistribution_history rh
  12311.         where
  12312.         rh.agent_id = @agent_id and
  12313.         time <= @time_up
  12314.         order by timestamp DESC
  12315.  
  12316.     select  runstatus, 
  12317.         'time' = convert(nvarchar(12), time, 112) +
  12318.                  substring(convert(nvarchar(24), time, 121), 11, 13), 
  12319.         comments, duration, 
  12320.         delivery_rate,
  12321.         delivery_latency,
  12322.         /* delivery_time */ 0,  
  12323.         delivered_transactions, delivered_commands, average_commands, 
  12324.         error_id            
  12325.         from MSdistribution_history rh
  12326.         where
  12327.         rh.agent_id = @agent_id and
  12328.         start_time = @start_time
  12329.         order by timestamp desc
  12330. GO
  12331.  
  12332.  
  12333. raiserror(15339,-1,-1,'sp_MSadd_merge_history')
  12334. go
  12335. CREATE PROCEDURE sp_MSadd_merge_history
  12336. @agent_id       int,        
  12337. @runstatus      int, 
  12338. @comments       nvarchar(255),
  12339. @delivery_time  int = 0,                    /* Milliseconds */
  12340. @publisher_insertcount  int = 0,
  12341. @publisher_updatecount  int = 0,
  12342. @publisher_deletecount  int = 0,
  12343. @publisher_conflictcount int = 0,
  12344. @subscriber_insertcount int = 0,
  12345. @subscriber_updatecount int = 0,
  12346. @subscriber_deletecount int = 0,
  12347. @subscriber_conflictcount int = 0,
  12348. @log_error bit = 0,
  12349. @perfmon_increment bit = 1,
  12350. @update_existing_row bit = 0,
  12351. @updateable_row bit = 1,     -- used to override history verbose level to decide
  12352.                             -- whether the row being added can be updated by another.    
  12353. @do_raiserror bit = 1
  12354. AS
  12355.  
  12356.     DECLARE @current_time datetime
  12357.     DECLARE @start_time datetime
  12358.     DECLARE @duration int
  12359.     DECLARE @delivery_rate float
  12360.     DECLARE @perfmon_delivery_rate int
  12361.     DECLARE @perfmon_conflict_count int
  12362.     DECLARE @delivered_rows int
  12363.     DECLARE @delivery_seconds float
  12364.     DECLARE @changes int
  12365.  
  12366.     DECLARE @delivery_time_old  int
  12367.     DECLARE @delivered_rows_old int
  12368.     DECLARE @publisher_insertcount_old  int 
  12369.     DECLARE @publisher_updatecount_old  int 
  12370.     DECLARE @publisher_deletecount_old  int 
  12371.     DECLARE @publisher_conflictcount_old int 
  12372.     DECLARE @subscriber_insertcount_old int 
  12373.     DECLARE @subscriber_updatecount_old int 
  12374.     DECLARE @subscriber_deletecount_old int 
  12375.     DECLARE @subscriber_conflictcount_old int 
  12376.     DECLARE @publisher_id smallint
  12377.     DECLARE @subscriber_id smallint
  12378.     DEClARE @error_id int 
  12379.     DECLARE @startup int
  12380.     DECLARE @succeed int
  12381.     DECLARE @retry int
  12382.     DECLARE @inprogress int
  12383.     DECLARE @failure int
  12384.     DECLARE @idle int
  12385.     DECLARE @lastrow_timestamp timestamp
  12386.     DECLARE @agent_name nvarchar(100)
  12387.     DECLARE @publisher sysname
  12388.     DECLARE @publisher_db sysname
  12389.     DECLARE @publication sysname
  12390.     DECLARE @retcode int
  12391.     DECLARE @existing_row_updateble bit
  12392.     DECLARE @this_row_updateable bit
  12393.  
  12394.     /* 
  12395.     ** Status const defined in sqlrepl.h 
  12396.     */
  12397.     set @startup = 1
  12398.     set @succeed = 2
  12399.     set @inprogress = 3
  12400.     set @idle = 4
  12401.     set @retry = 5
  12402.     set @failure = 6
  12403.  
  12404.     select  @delivery_time_old  = 0
  12405.     select  @publisher_insertcount_old   = 0
  12406.     select  @publisher_updatecount_old   = 0
  12407.     select  @publisher_deletecount_old   = 0
  12408.     select  @publisher_conflictcount_old  = 0
  12409.     select  @subscriber_insertcount_old  = 0
  12410.     select  @subscriber_updatecount_old  = 0
  12411.     select  @subscriber_deletecount_old  = 0
  12412.     select  @subscriber_conflictcount_old  = 0
  12413.     select    @existing_row_updateble = 1
  12414.     select  @this_row_updateable = 1
  12415.  
  12416.     if (@updateable_row = 0)
  12417.     begin
  12418.         select @this_row_updateable = 0
  12419.     end
  12420.  
  12421.     -- Security Check
  12422.     exec @retcode = dbo.sp_MScheck_pull_access
  12423.         @agent_id = @agent_id,
  12424.         @agent_type = 1 -- merge agent
  12425.     if @@error <> 0 or @retcode <> 0
  12426.         return (1)
  12427.  
  12428.     SELECT @current_time = GETDATE()
  12429.  
  12430.     -- Update Perfmon counter
  12431.     if @perfmon_increment = 1
  12432.     begin
  12433.         if @runstatus = @startup
  12434.             dbcc incrementinstance ("SQL Replication Agents", "Running", "Merge", 1)
  12435.         else if (@runstatus = @succeed or @runstatus = @retry or @runstatus = @failure)
  12436.             dbcc incrementinstance ("SQL Replication Agents", "Running", "Merge", -1)
  12437.     end
  12438.  
  12439.     SELECT @agent_name = name, @publisher_id = publisher_id, @publisher_db = publisher_db, 
  12440.         @publication = publication from MSmerge_agents where id = @agent_id
  12441.     select @publisher = srvname from master..sysservers where srvid = @publisher_id
  12442.  
  12443.     /* Get start_time for latest agent run */
  12444.     IF @runstatus <> 1 --Start status
  12445.     BEGIN
  12446.         SELECT TOP 1 @start_time = start_time, @lastrow_timestamp = timestamp
  12447.             FROM MSmerge_history (rowlock)
  12448.         WHERE  agent_id = @agent_id ORDER BY timestamp DESC
  12449.     END
  12450.     ELSE
  12451.        SELECT @start_time = @current_time
  12452.  
  12453.     IF @runstatus = @inprogress
  12454.         BEGIN
  12455.             SELECT TOP 1 @publisher_insertcount_old = publisher_insertcount ,
  12456.                      @publisher_updatecount_old = publisher_updatecount, 
  12457.                      @publisher_deletecount_old = publisher_deletecount,
  12458.                      @publisher_conflictcount_old = publisher_conflictcount,
  12459.                      @subscriber_insertcount_old = subscriber_insertcount, 
  12460.                      @subscriber_updatecount_old = subscriber_updatecount,
  12461.                      @subscriber_deletecount_old = subscriber_deletecount,
  12462.                      @subscriber_conflictcount_old = subscriber_conflictcount,
  12463.                      @delivery_time_old = delivery_time,
  12464.                      @existing_row_updateble = updateable_row
  12465.             FROM MSmerge_history (rowlock)
  12466.             WHERE  agent_id = @agent_id ORDER BY timestamp DESC
  12467.         
  12468.             select @delivered_rows_old = @publisher_insertcount_old + 
  12469.                              @publisher_updatecount_old +
  12470.                              @publisher_deletecount_old +
  12471.                              @subscriber_updatecount_old +
  12472.                              @subscriber_insertcount_old +
  12473.                              @subscriber_deletecount_old 
  12474.         END
  12475.  
  12476.     /* Use the current time if no corresponding start_up message logged */
  12477.     IF @start_time IS NULL
  12478.        SELECT @start_time = @current_time
  12479.  
  12480.     /* Calculate agent run duration */
  12481.     SELECT @duration = DATEDIFF(second, @start_time, @current_time) 
  12482.                              
  12483.     select @delivered_rows = @publisher_insertcount + 
  12484.                              @publisher_updatecount +
  12485.                              @publisher_deletecount +
  12486.                              @subscriber_updatecount +
  12487.                              @subscriber_insertcount +
  12488.                              @subscriber_deletecount 
  12489.  
  12490.     -- Set Perfmon counters
  12491.     if @runstatus = @idle or @runstatus = @inprogress
  12492.     begin
  12493.         
  12494.         dbcc addinstance ("SQL Replication Merge", @agent_name)
  12495.  
  12496.         set @changes = @publisher_insertcount + @publisher_updatecount + @publisher_deletecount                             
  12497.         dbcc incrementinstance ("SQL Replication Merge", "Downloaded Changes/sec", @agent_name, @changes)
  12498.  
  12499.         set @changes = @subscriber_updatecount + @subscriber_insertcount + @subscriber_deletecount 
  12500.         dbcc incrementinstance ("SQL Replication Merge", "Uploaded Changes/sec", @agent_name, @changes)
  12501.  
  12502.         set @perfmon_conflict_count = @publisher_conflictcount + @subscriber_conflictcount
  12503.         dbcc incrementinstance ("SQL Replication Merge", "Conflicts/sec", @agent_name, @perfmon_conflict_count)
  12504.     end
  12505.  
  12506.     if @runstatus = @inprogress -- if it is in progress, then do incremental change
  12507.     begin
  12508.         select @publisher_insertcount = @publisher_insertcount_old + @publisher_insertcount
  12509.         select      @publisher_updatecount = @publisher_updatecount_old + @publisher_updatecount
  12510.         select      @publisher_deletecount = @publisher_deletecount_old + @publisher_deletecount
  12511.         select      @publisher_conflictcount = @publisher_conflictcount_old + @publisher_conflictcount
  12512.         select      @subscriber_insertcount = @subscriber_insertcount_old + @subscriber_insertcount
  12513.         select     @subscriber_updatecount = @subscriber_updatecount_old + @subscriber_updatecount
  12514.         select     @subscriber_deletecount = @subscriber_deletecount_old + @subscriber_deletecount
  12515.         select     @subscriber_conflictcount = @subscriber_conflictcount_old + @subscriber_conflictcount
  12516.  
  12517.         select  @delivery_time = @delivery_time_old + @delivery_time
  12518.         select @delivered_rows = @delivered_rows + @delivered_rows_old
  12519.     end
  12520.     
  12521.     /* Calculate delivery_rate */
  12522.     IF @delivery_time <> 0 
  12523.         select @delivery_seconds = @delivery_time/1000
  12524.     ELSE
  12525.         select @delivery_seconds = 0
  12526.  
  12527.     IF @delivery_seconds <> 0 
  12528.        SELECT @delivery_rate = (@delivered_rows * 1.0) / @delivery_seconds
  12529.     ELSE
  12530.        SELECT @delivery_rate = 0
  12531.  
  12532.     /* 
  12533.     ** Set error id to 0 unless the user want to log errors associate with this 
  12534.     ** history message.
  12535.     */
  12536.     SELECT @error_id = 0
  12537.     IF @log_error = 1
  12538.         -- Ignore errors here. @error_id will be set to 0 in case of errors  
  12539.         EXEC dbo.sp_MSget_new_errorid @error_id OUTPUT
  12540.  
  12541.     -- Insert idle record or update if history record is already 'idle'
  12542.     IF (@existing_row_updateble = 1) and (@runstatus = @idle or @update_existing_row = 1)
  12543.     begin
  12544.         -- Attempt to update the last row if it is IDLE
  12545.         UPDATE MSmerge_history SET runstatus = @runstatus, time = @current_time, duration = @duration,
  12546.             comments = @comments,
  12547.             delivery_time = @delivery_time, 
  12548.             delivery_rate = @delivery_rate, 
  12549.             publisher_insertcount = @publisher_insertcount,
  12550.             publisher_updatecount = @publisher_updatecount,
  12551.             publisher_deletecount = @publisher_deletecount,
  12552.             publisher_conflictcount = @publisher_conflictcount,
  12553.             subscriber_insertcount = @subscriber_insertcount,
  12554.             subscriber_updatecount = @subscriber_updatecount,
  12555.             subscriber_deletecount = @subscriber_deletecount,
  12556.             subscriber_conflictcount = @subscriber_conflictcount,
  12557.             updateable_row = @this_row_updateable
  12558.             WHERE
  12559.             agent_id = @agent_id and
  12560.             timestamp = @lastrow_timestamp and
  12561.             (runstatus = @runstatus or 
  12562.             (@update_existing_row = 1 and runstatus in (@idle, @inprogress) and @runstatus in (@idle, @inprogress)))
  12563.  
  12564.         -- Insert idle record if there is not one
  12565.         if @@ROWCOUNT = 0
  12566.             INSERT INTO MSmerge_history
  12567.             (
  12568.             agent_id, runstatus, start_time, time, duration, comments, delivery_time, delivery_rate, publisher_insertcount,
  12569.             publisher_updatecount, publisher_deletecount, publisher_conflictcount, subscriber_insertcount, subscriber_updatecount,
  12570.             subscriber_deletecount, subscriber_conflictcount, error_id, timestamp, updateable_row
  12571.             )
  12572.             VALUES 
  12573.             (
  12574.             @agent_id, @runstatus, @start_time, @current_time, 
  12575.             @duration, @comments,  @delivery_time, @delivery_rate, 
  12576.             @publisher_insertcount, @publisher_updatecount, @publisher_deletecount, @publisher_conflictcount, 
  12577.             @subscriber_insertcount, @subscriber_updatecount, @subscriber_deletecount, @subscriber_conflictcount, 
  12578.             @error_id, NULL, @this_row_updateable
  12579.             )
  12580.     end
  12581.     else
  12582.     begin
  12583.         INSERT INTO MSmerge_history 
  12584.         (
  12585.             agent_id, runstatus, start_time, time, duration, comments, delivery_time, delivery_rate, publisher_insertcount,
  12586.             publisher_updatecount, publisher_deletecount, publisher_conflictcount, subscriber_insertcount, subscriber_updatecount,
  12587.             subscriber_deletecount, subscriber_conflictcount, error_id, timestamp, updateable_row
  12588.         )
  12589.         VALUES 
  12590.         (
  12591.         @agent_id, @runstatus, @start_time, @current_time, 
  12592.         @duration, @comments, @delivery_time, @delivery_rate, 
  12593.         @publisher_insertcount, @publisher_updatecount, @publisher_deletecount, @publisher_conflictcount, 
  12594.         @subscriber_insertcount, @subscriber_updatecount, @subscriber_deletecount, @subscriber_conflictcount, 
  12595.         @error_id, NULL, @this_row_updateable
  12596.         )
  12597.     end
  12598.  
  12599.     -- Update global replication agent status table
  12600.     exec dbo.sp_MSupdate_replication_status 
  12601.         @publisher, 
  12602.         @publisher_db,
  12603.         @publication,
  12604.         @publication_type = 2,
  12605.         @agent_type = 4,
  12606.         @agent_name = @agent_name,
  12607.         @status = @runstatus
  12608.  
  12609.     -- Raise the appropriate error
  12610.     if @do_raiserror = 1
  12611.         exec dbo.sp_MSrepl_raiserror 'Merge', @agent_name, @runstatus, @comments
  12612.  
  12613.     IF @@ERROR <> 0
  12614.         RETURN (1)
  12615.  
  12616.     RETURN (0)
  12617. GO   
  12618.  
  12619. raiserror(15339,-1,-1,'sp_MSenum_merge')
  12620. go
  12621. create procedure sp_MSenum_merge
  12622. @name nvarchar(100) = '%',
  12623. @show_distdb bit = 0
  12624. as
  12625.     set nocount on
  12626.  
  12627.     declare @publisher sysname
  12628.     declare @publisher_id smallint
  12629.     declare @publisher_db sysname
  12630.     declare @subscriber sysname
  12631.     declare @subscriber_id smallint
  12632.     declare @subscriber_db sysname
  12633.     declare @subscriber_name sysname
  12634.     declare @subscription_type int
  12635.     declare @publication sysname
  12636.     declare @status int
  12637.     declare @start_time nvarchar(24)
  12638.     declare @time nvarchar(24)
  12639.     declare @duration int
  12640.     declare @comments nvarchar(255)
  12641.     declare @publisher_insertcount int
  12642.     declare @publisher_updatecount int
  12643.     declare @publisher_deletecount int
  12644.     declare @publisher_conflictcount int
  12645.     declare @subscriber_insertcount int
  12646.     declare @subscriber_updatecount int
  12647.     declare @subscriber_deletecount int
  12648.     declare @subscriber_conflictcount int
  12649.     declare @delivery_rate int
  12650.     declare @agent_name nvarchar(100)
  12651.     declare @error_id int
  12652.     declare @job_id binary(16)
  12653.     declare @local_job bit
  12654.     declare @profile_id int
  12655.     declare @agent_id int
  12656.     declare @current_time datetime
  12657.     declare @last_timestamp binary(8)
  12658.  
  12659.     set @current_time = getdate()
  12660.  
  12661.     create table #merge_agent (name nvarchar(100) NOT NULL, status int NOT NULL,
  12662.         publisher sysname NOT NULL, publisher_db sysname NOT NULL, publication sysname NULL,
  12663.         subscriber sysname NOT NULL, subscriber_db sysname NOT NULL, subscription_type int NULL,
  12664.         start_time nvarchar(24) NULL, time nvarchar(24) NULL, duration int NULL, 
  12665.         comments nvarchar(255) NULL, delivery_rate int NULL,
  12666.         publisher_insertcount int NULL, publisher_updatecount int NULL, publisher_deletecount int NULL,
  12667.         publisher_conficts int NULL, 
  12668.         subscriber_insertcount int NULL, subscriber_updatecount int NULL, subscriber_deletecount int NULL,
  12669.         subscriber_conficts int NULL, error_id int NULL, job_id binary(16) NULL,
  12670.         local_job bit NULL, profile_id int NOT NULL, agent_id int NOT NULL, last_timestamp binary(8) NOT NULL)
  12671.  
  12672.     declare hC CURSOR LOCAL FAST_FORWARD FOR
  12673.         select p.publisher_id, a.subscriber_id, a.publisher_db, a.subscriber_db, 
  12674.             p.publication, a.name, a.local_job, a.job_id, a.profile_id, a.id, a.subscriber_name
  12675.             from MSmerge_agents a, MSpublications p
  12676.             where 
  12677.             a.name LIKE @name and
  12678.             a.publisher_id = p.publisher_id and
  12679.             a.publisher_db = p.publisher_db and
  12680.             a.publication = p.publication
  12681.  
  12682.         for read only
  12683.  
  12684.  
  12685.     OPEN hC
  12686.     FETCH hC INTO @publisher_id, @subscriber_id, @publisher_db, @subscriber_db,
  12687.         @publication, @agent_name, @local_job, @job_id, @profile_id, @agent_id, @subscriber_name
  12688.  
  12689.     WHILE (@@fetch_status <> -1)
  12690.     begin
  12691.  
  12692.         /* Initialize the values for no history case */
  12693.         select @status = 0,
  12694.             @start_time = NULL,
  12695.             @time = NULL, 
  12696.             @duration = NULL, 
  12697.             @comments = NULL,
  12698.             @publisher_insertcount = 0,
  12699.             @publisher_deletecount = 0,
  12700.             @publisher_updatecount = 0,
  12701.             @publisher_conflictcount = 0,
  12702.             @subscriber_insertcount = 0,
  12703.             @subscriber_deletecount = 0,
  12704.             @subscriber_updatecount = 0,
  12705.             @subscriber_conflictcount = 0,
  12706.             @delivery_rate = 0,
  12707.             @error_id = NULL, 
  12708.             @last_timestamp = 0x00000000
  12709.  
  12710.         select @status = isnull(runstatus,0),
  12711.             @start_time = convert(nvarchar(12), start_time, 112) +
  12712.                           substring(convert(nvarchar(24), start_time, 121), 11, 13),
  12713.             @time = convert(nvarchar(12), time, 112) +
  12714.                     substring(convert(nvarchar(24), time, 121), 11, 13), 
  12715.             @duration = DATEDIFF(second, start_time, @current_time), 
  12716.             @comments = comments,
  12717.             @publisher_insertcount = publisher_insertcount,
  12718.             @publisher_deletecount = publisher_deletecount,
  12719.             @publisher_updatecount =  publisher_updatecount,
  12720.             @publisher_conflictcount =  publisher_conflictcount,
  12721.             @subscriber_insertcount = subscriber_insertcount,
  12722.             @subscriber_deletecount = subscriber_deletecount,
  12723.             @subscriber_updatecount =  subscriber_updatecount,
  12724.             @subscriber_conflictcount =  subscriber_conflictcount,
  12725.             -- Note: return average rate here !!! delivery_rate column is current rate
  12726.             @delivery_rate = 
  12727.                 case    when duration <> 0 then 
  12728.                             (publisher_insertcount + publisher_updatecount +
  12729.                             publisher_deletecount + subscriber_insertcount + 
  12730.                             subscriber_updatecount + subscriber_deletecount)/duration
  12731.                         when duration = 0 then 0
  12732.                 end, 
  12733.             @error_id = error_id, @last_timestamp = timestamp
  12734.             from MSmerge_history
  12735.             where
  12736.                 agent_id = @agent_id and
  12737.                 timestamp = (select max(timestamp) from MSmerge_history mh2
  12738.                     where mh2.agent_id = @agent_id)
  12739.  
  12740.         select @publisher = srvname from master..sysservers where srvid = @publisher_id
  12741.  
  12742.         -- For non anonymous agents, @subscriber_name is null 
  12743.         if @subscriber_name is NULL
  12744.             begin
  12745.                 select @subscriber = srvname from master..sysservers where srvid = @subscriber_id
  12746.                 if @local_job = 1 select @subscription_type = 0
  12747.                     else select @subscription_type = 1
  12748.             end
  12749.         else 
  12750.             begin
  12751.                 select @subscriber = @subscriber_name
  12752.                 select @subscriber_db = @subscriber_db + '-' +  convert(nvarchar(4), @agent_id)
  12753.                 select @subscription_type = 2   -- anonymous type
  12754.             end
  12755.         
  12756.         insert into #merge_agent values (@agent_name, @status, @publisher,
  12757.             @publisher_db, @publication, @subscriber, @subscriber_db, @subscription_type,
  12758.             @start_time, @time, @duration, @comments, @delivery_rate,
  12759.             @publisher_insertcount, @publisher_updatecount, @publisher_deletecount, 
  12760.             @publisher_conflictcount,
  12761.             @subscriber_insertcount, @subscriber_updatecount, @subscriber_deletecount, 
  12762.             @subscriber_conflictcount,
  12763.             @error_id, @job_id, @local_job, @profile_id, @agent_id, @last_timestamp)
  12764.  
  12765.         FETCH hC INTO @publisher_id, @subscriber_id, @publisher_db, @subscriber_db,
  12766.             @publication, @agent_name, @local_job, @job_id, @profile_id,
  12767.             @agent_id, @subscriber_name
  12768.         end
  12769.  
  12770.     if @show_distdb = 0
  12771.         select * from #merge_agent 
  12772.     else 
  12773.         select 'dbname' = DB_NAME(), * from #merge_agent
  12774.  
  12775.     drop table #merge_agent
  12776.     close hC
  12777.     deallocate hC
  12778.  
  12779. GO
  12780.  
  12781.  
  12782. raiserror(15339,-1,-1,'sp_MSenum_merge_s')
  12783. go
  12784.  
  12785. create procedure sp_MSenum_merge_s
  12786. @name nvarchar(100), 
  12787. @hours int = 0, /* @hours < 0 will return TOP 100 */
  12788. @session_type int = 1 /* Return all sessions */
  12789. as
  12790.     set nocount on
  12791.  
  12792.     declare @succeed int
  12793.     declare @agent_id int
  12794.     declare @retry int
  12795.     declare @failure int
  12796.     declare @min_time datetime
  12797.  
  12798.     /* 
  12799.     ** Status const defined in sqlrepl.h 
  12800.     */
  12801.     select @succeed = 2
  12802.     select @retry = 5
  12803.     select @failure = 6
  12804.  
  12805.     select @agent_id = id from MSmerge_agents where name = @name
  12806.  
  12807.     /* Get date starting point */
  12808.     IF @hours < 0
  12809.     BEGIN
  12810.         select  top 100 runstatus, 
  12811.             'start_time' = convert(nvarchar(12), start_time, 112) +
  12812.                            substring(convert(nvarchar(24), start_time, 121), 11, 13), 
  12813.             'time' = convert(nvarchar(12), time, 112) +
  12814.                      substring(convert(nvarchar(24), time, 121), 11, 13), 
  12815.             comments, duration, 
  12816.             -- Note: return average rate here !!! delivery_rate column is current rate
  12817.             case    when duration <> 0 then 
  12818.                             (publisher_insertcount + publisher_updatecount +
  12819.                             publisher_deletecount + subscriber_insertcount + 
  12820.                             subscriber_updatecount + subscriber_deletecount)/duration
  12821.                     when duration = 0 then 0
  12822.             end, 
  12823.             publisher_insertcount, publisher_updatecount, publisher_deletecount, publisher_conflictcount,
  12824.             subscriber_insertcount, subscriber_updatecount, subscriber_deletecount, subscriber_conflictcount,
  12825.             'action_count' = (select count(*) from MSmerge_history where
  12826.                 start_time = rh.start_time and agent_id=@agent_id),
  12827.             error_id
  12828.             from MSmerge_history rh
  12829.             where
  12830.             agent_id = @agent_id and
  12831.             ((@session_type = 1 and
  12832.             (runstatus = @succeed or
  12833.             runstatus = @retry or
  12834.             timestamp = (select max(timestamp) from MSmerge_history rh2 where
  12835.                 rh2.agent_id = @agent_id))) or 
  12836.             runstatus = @failure)
  12837.             order by timestamp desc
  12838.     END
  12839.     ELSE
  12840.     BEGIN
  12841.         IF @hours = 0
  12842.         BEGIN
  12843.             select @min_time = NULL
  12844.         END
  12845.         ELSE
  12846.         BEGIN
  12847.             select @min_time = dateadd(hour, -@hours, getdate())
  12848.         END
  12849.  
  12850.         select  runstatus, 
  12851.             'start_time' = convert(nvarchar(12), start_time, 112) +
  12852.                            substring(convert(nvarchar(24), start_time, 121), 11, 13), 
  12853.             'time' = convert(nvarchar(12), time, 112) +
  12854.                      substring(convert(nvarchar(24), time, 121), 11, 13), 
  12855.             comments, duration, 
  12856.             -- Note: return average rate here !!! delivery_rate column is current rate
  12857.             case    when duration <> 0 then 
  12858.                             (publisher_insertcount + publisher_updatecount +
  12859.                             publisher_deletecount + subscriber_insertcount + 
  12860.                             subscriber_updatecount + subscriber_deletecount)/duration
  12861.                     when duration = 0 then 0
  12862.             end, 
  12863.             publisher_insertcount, publisher_updatecount, publisher_deletecount, publisher_conflictcount,
  12864.             subscriber_insertcount, subscriber_updatecount, subscriber_deletecount, subscriber_conflictcount,
  12865.             'action_count' = (select count(*) from MSmerge_history where
  12866.                 start_time = rh.start_time and agent_id=@agent_id),
  12867.             error_id
  12868.             from MSmerge_history rh
  12869.             where
  12870.             agent_id = @agent_id and
  12871.             ((@session_type = 1 and
  12872.             (runstatus = @succeed or
  12873.             runstatus = @retry or
  12874.             timestamp = (select max(timestamp) from MSmerge_history rh2 where
  12875.                 rh2.agent_id = @agent_id))) or 
  12876.             runstatus = @failure) and
  12877.             (time >= @min_time or @min_time IS NULL)
  12878.             order by timestamp desc
  12879.     END
  12880. GO
  12881.  
  12882. raiserror(15339,-1,-1,'sp_MSenum_merge_sd')
  12883. go
  12884.  
  12885. create procedure sp_MSenum_merge_sd
  12886. @name nvarchar(100),
  12887. @time datetime = NULL
  12888. as
  12889.     set nocount on
  12890.  
  12891.     declare @start_time datetime
  12892.     declare @agent_id int
  12893.     declare @time_up datetime
  12894.  
  12895.     select @agent_id = id from MSmerge_agents where name=@name
  12896.     
  12897.     IF @time IS NULL
  12898.         select @time = GETDATE()
  12899.  
  12900.     /*
  12901.     ** Minute-approximate @time can be used.
  12902.     ** Note: The select only return datetime data with minute precision
  12903.     */
  12904.     IF  DATEPART(second, @time) = 0 AND
  12905.         DATEPART(millisecond, @time) = 0
  12906.     BEGIN
  12907.         SELECT @time_up = DATEADD(second, +59, @time)
  12908.         SELECT @time_up = DATEADD(millisecond, +999, @time)
  12909.     END
  12910.     ELSE
  12911.         SELECT @time_up = @time
  12912.         
  12913.  
  12914.     select top 1 @start_time = start_time           
  12915.          from MSmerge_history rh
  12916.         where
  12917.         rh.agent_id = @agent_id and
  12918.         time <= @time_up
  12919.         order by timestamp DESC
  12920.  
  12921.     select  runstatus, 
  12922.             'time' = convert(nvarchar(12), time, 112) + 
  12923.                      substring(convert(nvarchar(24), time, 121), 11, 13),
  12924.             comments, duration, 
  12925.         -- Note: return average rate here !!! delivery_rate column is current rate
  12926.         case    when duration <> 0 then 
  12927.                         (publisher_insertcount + publisher_updatecount +
  12928.                         publisher_deletecount + subscriber_insertcount + 
  12929.                         subscriber_updatecount + subscriber_deletecount)/duration
  12930.                 when duration = 0 then 0
  12931.         end, 
  12932.         publisher_insertcount, publisher_updatecount, publisher_deletecount, publisher_conflictcount,
  12933.         subscriber_insertcount, subscriber_updatecount, subscriber_deletecount, subscriber_conflictcount,
  12934.         error_id            
  12935.         from MSmerge_history rh
  12936.         where
  12937.         rh.agent_id = @agent_id and
  12938.         start_time = @start_time
  12939.         order by timestamp desc
  12940. GO
  12941.  
  12942. raiserror(15339,-1,-1,'sp_MSadd_repl_error')
  12943. GO
  12944.  
  12945. CREATE PROCEDURE sp_MSadd_repl_error (
  12946. @id                 int,
  12947. @error_type_id      int,
  12948. @source_type_id     int,
  12949. @source_name        sysname,
  12950. @error_code         sysname,
  12951. @error_text         ntext
  12952. )
  12953. AS
  12954.     declare @retcode int
  12955.  
  12956.     -- Security Check
  12957.     -- require the login to be in cache regardless of the publication id and agent_id.
  12958.     -- This means that once a agent get into the distribution db, it
  12959.     -- can add any error.   
  12960.     exec @retcode = dbo.sp_MScheck_pull_access
  12961.     if @@error <> 0 or @retcode <> 0
  12962.         return (1)
  12963.  
  12964.     INSERT INTO MSrepl_errors VALUES (@id, getdate(), @error_type_id, @source_type_id,
  12965.         @source_name, @error_code, @error_text)
  12966.  
  12967.     IF @@ERROR <> 0
  12968.     BEGIN
  12969.        RETURN (1)
  12970.     END
  12971.  
  12972.     return (0)
  12973. GO   
  12974.  
  12975.  
  12976. raiserror(15339,-1,-1,'sp_MSadd_repl_alert')
  12977. GO
  12978.  
  12979. CREATE PROCEDURE sp_MSadd_repl_alert (
  12980. @agent_type         int,
  12981. @agent_id           int,
  12982. @error_id           int,
  12983. @alert_error_code   int,
  12984. @xact_seqno         varbinary(16),      
  12985. @command_id         int,
  12986. @publisher          sysname,
  12987. @publisher_db       sysname,
  12988. @subscriber         sysname,
  12989. @subscriber_db      sysname,
  12990. @alert_error_text   ntext
  12991. )
  12992. AS
  12993.     SET NOCOUNT ON
  12994.  
  12995.     declare @retcode int
  12996.     declare @article sysname
  12997.     declare @article_id int
  12998.     declare @destination_object sysname
  12999.     declare @source_object sysname
  13000.     declare @publisher_id int
  13001.     declare @publication sysname
  13002.     declare @publication_id int
  13003.     declare @publication_type int
  13004.     declare @subscriber_id int
  13005.     declare @publisher_database_id int
  13006.     declare @agent_type2 int
  13007.  
  13008.     -- Security Check
  13009.     if @agent_type = 3
  13010.         select @agent_type2 = 0 -- distribution
  13011.     else if @agent_type = 4
  13012.         select @agent_type2 = 1 -- merge
  13013.  
  13014.     if @agent_type2 is not null 
  13015.     begin
  13016.         exec @retcode = dbo.sp_MScheck_pull_access
  13017.                 @agent_id = @agent_id,
  13018.                 @agent_type = @agent_type2
  13019.         if @@error <> 0 or @retcode <> 0
  13020.             return (1)
  13021.     end
  13022.     else
  13023.     begin
  13024.         if is_member('db_owner') = 0
  13025.         begin
  13026.             RAISERROR (14126, 16, -1)
  13027.             return(1)
  13028.         end
  13029.     end
  13030.  
  13031.     select @publisher_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)
  13032.     select @subscriber_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  13033.     
  13034.     select @publisher_database_id = id from MSpublisher_databases 
  13035.     where publisher_id = @publisher_id and publisher_db = @publisher_db
  13036.  
  13037.     select @article_id = article_id from MSrepl_commands
  13038.     where publisher_database_id = @publisher_database_id
  13039.     and xact_seqno = @xact_seqno
  13040.     and command_id = @command_id
  13041.  
  13042.     select @publication = mp.publication, @publication_id = mp.publication_id, @publication_type = mp.publication_type
  13043.     from MSpublications as mp, MSsubscriptions as ms
  13044.     where mp.publisher_id = ms.publisher_id
  13045.     and mp.publisher_db = ms.publisher_db
  13046.     and mp.publication_id = ms.publication_id
  13047.     and ms.publisher_id = @publisher_id
  13048.     and ms.publisher_db = @publisher_db
  13049.     and ms.subscriber_id = @subscriber_id
  13050.     and ms.subscriber_db = @subscriber_db
  13051.     and ms.article_id = @article_id
  13052.  
  13053.     select @article = article, @destination_object = destination_object, @source_object = source_object 
  13054.     from MSarticles
  13055.     where article_id = @article_id
  13056.         and publisher_id = @publisher_id
  13057.         and publisher_db = @publisher_db
  13058.         and publication_id = @publication_id
  13059.  
  13060.      INSERT INTO msdb.dbo.sysreplicationalerts (status, agent_type , agent_id, error_id, alert_error_code, time, publisher,
  13061.                                 publisher_db, publication, publication_type, subscriber, subscriber_db,
  13062.                                 article, destination_object, source_object, alert_error_text)
  13063.                 VALUES (0, @agent_type, @agent_id, @error_id, @alert_error_code, getdate(), @publisher, 
  13064.                         @publisher_db, @publication, @publication_type, @subscriber, @subscriber_db, 
  13065.                         @article, @destination_object, @source_object, @alert_error_text)
  13066.     
  13067.     IF @@ERROR <> 0
  13068.     BEGIN
  13069.        RETURN (1)
  13070.     END
  13071.  
  13072.     return (0)
  13073. GO   
  13074.  
  13075. raiserror(15339,-1,-1,'sp_MSadd_replmergealert')
  13076. GO
  13077.  
  13078. CREATE PROCEDURE sp_MSadd_replmergealert (
  13079. @agent_type         int,
  13080. @agent_id           int,
  13081. @error_id           int,
  13082. @alert_error_code   int,
  13083. @publisher          sysname,
  13084. @publisher_db       sysname,
  13085. @publication        sysname,
  13086. @publication_type   int,
  13087. @subscriber         sysname,
  13088. @subscriber_db      sysname,
  13089. @article            sysname,
  13090. @destination_object sysname,
  13091. @source_object      sysname,
  13092. @alert_error_text   ntext
  13093. )
  13094. AS
  13095.     SET NOCOUNT ON
  13096.  
  13097.     INSERT INTO msdb.dbo.sysreplicationalerts (status, agent_type , agent_id, error_id, alert_error_code, time, publisher,
  13098.                                 publisher_db, publication, publication_type, subscriber, subscriber_db,
  13099.                                 article, destination_object, source_object, alert_error_text)
  13100.                 VALUES (0, @agent_type, @agent_id, @error_id, @alert_error_code, getdate(), @publisher, 
  13101.                         @publisher_db, @publication, @publication_type, @subscriber, @subscriber_db, 
  13102.                         @article, @destination_object, @source_object, @alert_error_text)
  13103.     
  13104.     IF @@ERROR <> 0
  13105.     BEGIN
  13106.        RETURN (1)
  13107.     END
  13108.  
  13109.     return (0)
  13110. GO   
  13111.  
  13112.  
  13113. raiserror(15339,-1,-1,'sp_MSget_repl_error')
  13114. GO
  13115.  
  13116. create procedure sp_MSget_repl_error (
  13117. @id int
  13118. )
  13119. as
  13120.     set nocount on
  13121.     select  source_type_id, source_name, error_code, error_text, 
  13122.             convert(nvarchar(12), time, 112) + 
  13123.             substring(convert(nvarchar(24), time, 121), 11, 13),
  13124.             error_type_id
  13125.         from MSrepl_errors
  13126.         where
  13127.             id = @id and
  13128.             -- rows with error_type_id are placeholders
  13129.             error_type_id IS NOT NULL
  13130.         order by time ASC
  13131. GO
  13132.  
  13133.  
  13134. raiserror(15339,-1,-1,'sp_MSdist_activate_auto_sub')
  13135. go
  13136. CREATE PROCEDURE sp_MSdist_activate_auto_sub
  13137. @publisher_id int,
  13138. @publisher_db sysname,
  13139. @article_id int
  13140.  
  13141. as
  13142.     
  13143.   declare @automatic tinyint
  13144.   declare @active tinyint
  13145.   declare @subscribed tinyint
  13146.   
  13147.    set nocount on
  13148.  
  13149.     select @automatic = 1
  13150.  
  13151.     select @subscribed = 1
  13152.     select @active = 2
  13153.  
  13154.  
  13155.     begin transaction MSdist_activate_auto_sub
  13156.  
  13157.        update MSsubscriptions set status = @active,
  13158.             subscription_time = getdate()
  13159.            where
  13160.               publisher_id = @publisher_id and
  13161.               publisher_db = @publisher_db and
  13162.               article_id = @article_id and
  13163.               sync_type = @automatic and
  13164.               status = @subscribed
  13165.  
  13166.        if @@ERROR <> 0
  13167.           begin
  13168.           if @@trancount > 0
  13169.             rollback transaction MSdist_activate_auto_sub
  13170.           return (1)
  13171.           end
  13172.  
  13173.    commit transaction
  13174.  
  13175. GO
  13176.  
  13177. raiserror(15339,-1,-1,'sp_MSlock_auto_sub')
  13178. go
  13179. CREATE PROCEDURE sp_MSlock_auto_sub
  13180. @publisher_id int,
  13181. @publisher_db sysname,
  13182. @publication sysname,
  13183. @reset bit = 0  /* @reset = 1 is used for Scheduled Snapshot publications by snapshot */
  13184.  
  13185. as
  13186.     
  13187.   /* This sp only work for 7.0 publisher since it use the publication name */  
  13188.    set nocount on
  13189.  
  13190.     DECLARE @virtual smallint     /* const: virtual subscriber id */
  13191.     DECLARE @virtual_anonymous smallint /* const: virtual anonymous subscriber id */
  13192.     DECLARE @subscribed tinyint
  13193.     DECLARE @automatic tinyint
  13194.     DECLARE @publication_id int
  13195.     DECLARE @counter int
  13196.     DECLARE @independent_agent bit
  13197.     DECLARE @active tinyint
  13198.  
  13199.     SELECT @virtual = -1
  13200.     SELECT @virtual_anonymous = -2
  13201.     SELECT @subscribed = 1
  13202.     SELECT @active = 2
  13203.     SELECT @automatic = 1
  13204.  
  13205.     select @publication_id = publication_id , @independent_agent = independent_agent
  13206.         from MSpublications 
  13207.         where 
  13208.         publisher_id = @publisher_id and
  13209.         publisher_db = @publisher_db and
  13210.         publication = @publication 
  13211.  
  13212.  
  13213.     /* 
  13214.     ** Set exclusive lock on the rows that will be updated to prevent deadlock 
  13215.     **      in snapshot agent.
  13216.     ** Note: using UPDATE lock may cause deadlock with sp_MSget_repl_commands as following
  13217.     ** 1. The distribution agent gets shared lock on MSsubscriptions.
  13218.     ** 2. The snapshot agent gets update lock on MSsubscriptions.
  13219.     ** 3. The snapshot agent gets exclusive lock on MSrepl_commands (inserting into the table)
  13220.     ** 4. The distribution agent waits to get shared lock on MSrepl_commands
  13221.     ** 5. The snapshot agent waits to convert update lock to exclusive lock on MSrepl_subscriptions (updating the table).
  13222.     */
  13223.     --SELECT @counter = COUNT(*) FROM MSsubscriptions (ROWLOCK UPDLOCK)
  13224.     -- 1. Avoid defered updates: Don't update fields in the clusted index
  13225.     -- 2. Avoid updating fields in the where clause 
  13226.     UPDATE MSsubscriptions SET update_mode = update_mode 
  13227.       WHERE 
  13228.          publisher_id = @publisher_id and
  13229.          publisher_db = @publisher_db and
  13230.          publication_id = @publication_id and 
  13231.          /* virtual subscriptions are automatic sync type */
  13232.          sync_type = @automatic and 
  13233.          (status = @subscribed or 
  13234.          subscriber_id = @virtual or
  13235.          subscriber_id = @virtual_anonymous or
  13236.          @reset = 1) 
  13237. GO
  13238.  
  13239. raiserror(15339,-1,-1,'sp_MSget_new_xact_seqno')
  13240. go
  13241. CREATE PROCEDURE sp_MSget_new_xact_seqno
  13242. @publisher_id int,
  13243. @publisher_db sysname,
  13244. @len    tinyint
  13245.  
  13246. AS
  13247.    declare @new_xact_seqno varbinary(16)
  13248.    declare @old_xact_seqno varbinary(16)
  13249.    declare @tag int
  13250.    declare @datalen tinyint
  13251.    declare @publisher_database_id int
  13252.  
  13253.    set nocount on 
  13254.    select @old_xact_seqno = NULL
  13255.  
  13256.     -- Get publisher database id.
  13257.     SELECT @publisher_database_id = id from MSpublisher_databases where publisher_id = @publisher_id and 
  13258.         publisher_db = @publisher_db
  13259.  
  13260.    set rowcount 1
  13261.    select @old_xact_seqno = rt.xact_seqno
  13262.       from
  13263.       -- Prevent inserts
  13264.       MSrepl_transactions rt (HOLDLOCK PAGLOCK UPDLOCK)
  13265.       where 
  13266.          rt.publisher_database_id = @publisher_database_id 
  13267.          order by xact_seqno desc
  13268.    set rowcount 0
  13269.  
  13270.    
  13271.    if @old_xact_seqno IS NULL
  13272.    begin
  13273.         /* if nothing got selected, lock the entire table 
  13274.         ** Don't return meta data !!
  13275.         */
  13276.        select @old_xact_seqno = rt.xact_seqno
  13277.           from
  13278.           MSrepl_transactions rt (HOLDLOCK TABLOCKX)
  13279.           where 0 = 1
  13280.  
  13281.         select @old_xact_seqno = subscription_seqno from MSsubscriptions 
  13282.         where
  13283.             publisher_database_id = @publisher_database_id and
  13284.             subscription_seqno = (select MAX(subscription_seqno) from MSsubscriptions rs2
  13285.             where
  13286.                 rs2.publisher_database_id = @publisher_database_id)
  13287.    end
  13288.  
  13289.     select @datalen = datalength(@old_xact_seqno) 
  13290.     /* Plus one to the tag */
  13291.     if @datalen = @len
  13292.     begin
  13293.         select @tag = convert( int, convert( binary(4), substring( convert( nvarchar, @old_xact_seqno ), @datalen/2 - 2 + 1,2 ) ) )
  13294.         
  13295.         if @tag = 0xffffffff
  13296.         begin
  13297.             raiserror(21018, 16, -1)
  13298.             return(1)
  13299.         end
  13300.         /* avoid arithmatic overflow */
  13301.         if @tag = 0x7fffffff
  13302.             select @tag = 0x80000000
  13303.         else 
  13304.             select @tag = @tag + 1
  13305.  
  13306.         select @new_xact_seqno = 
  13307.         convert( varbinary, substring( convert(nvarchar, @old_xact_seqno), 1, @datalen/2-2)) +
  13308.         convert( VARBINARY(4), @tag )
  13309.  
  13310.     end
  13311.     /* Add a tag */
  13312.     else
  13313.     begin
  13314.         if @datalen + 4 <> @len
  13315.         begin
  13316.             -- We are in trouble if we reach here.
  13317.             return(1)
  13318.         end
  13319.         select @tag = 1
  13320.         select @new_xact_seqno = 
  13321.             @old_xact_seqno + CONVERT(VARBINARY(4), @tag) 
  13322.     end
  13323.  
  13324.    select @new_xact_seqno
  13325. GO
  13326.  
  13327.  
  13328.  
  13329. raiserror(15339,-1,-1,'sp_MSchange_publication')
  13330. go
  13331. CREATE PROCEDURE sp_MSchange_publication
  13332. @publisher sysname,
  13333. @publisher_db sysname,
  13334. @publication sysname,
  13335. @property sysname,
  13336. @value nvarchar(255)
  13337. as
  13338.  
  13339.     set nocount on
  13340.     
  13341.     declare @publisher_id smallint
  13342.     declare @publication_type int
  13343.     declare @retcode int
  13344.     declare @max_distretention int
  13345.     declare @retention_value int
  13346.     DECLARE @cmd    nvarchar(255)
  13347.     DECLARE @cmd2   nvarchar(255)
  13348.     DECLARE @cmd3   nvarchar(255)
  13349.  
  13350.  
  13351.  
  13352.     -- Check if publisher is a defined as a distribution publisher in the current database
  13353.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  13354.     if @retcode <> 0
  13355.     begin
  13356.         return(1)
  13357.     end
  13358.  
  13359.     /* Charater properties  */
  13360.  
  13361.     begin tran
  13362.  
  13363.     IF LOWER(@property) ='description'
  13364.     BEGIN
  13365.         UPDATE MSpublications SET description = @value
  13366.             WHERE   publisher_id = @publisher_id AND
  13367.                     publisher_db = @publisher_db AND
  13368.                     publication = @publication
  13369.         IF @@ERROR <> 0 
  13370.             goto UNDO
  13371.     END
  13372.     ELSE IF LOWER(@property) IN ('snapshot_agent')
  13373.     BEGIN
  13374.         -- local job name is internal and should not be changed
  13375.         if exists (select * from MSsnapshot_agents where
  13376.             publisher_id = @publisher_id and
  13377.             publication = @publication and
  13378.             publisher_db = @publisher_db and
  13379.             local_job = 1)
  13380.         begin
  13381.             raiserror(21030, 16, -1)
  13382.             goto UNDO
  13383.         end
  13384.  
  13385.         -- Drop and recreate
  13386.         exec @retcode = dbo.sp_MSdrop_snapshot_agent
  13387.             @publisher = @publisher,
  13388.             @publisher_db = @publisher_db,
  13389.             @publication = @publication
  13390.  
  13391.         IF @@ERROR <> 0 or @retcode <> 0
  13392.             goto UNDO
  13393.  
  13394.         exec @retcode = dbo.sp_MSadd_snapshot_agent
  13395.             @name = @value,
  13396.             @publisher = @publisher,
  13397.             @publisher_db = @publisher_db,
  13398.             @publication = @publication,
  13399.             @local_job = 0
  13400.  
  13401.         IF @@ERROR <> 0 or @retcode <> 0
  13402.             goto UNDO
  13403.     END
  13404.     ELSE IF LOWER(@property) IN ('logreader_agent')
  13405.     BEGIN
  13406.         -- local job name is internal and should not be changed
  13407.         if exists (select * from MSlogreader_agents where
  13408.             publisher_id = @publisher_id and
  13409.             publication = @publication and
  13410.             publisher_db = @publisher_db and
  13411.             local_job = 1)
  13412.         begin
  13413.             raiserror(21030, 16, -1)
  13414.             goto UNDO
  13415.         end
  13416.  
  13417.         -- Drop and recreate
  13418.         exec @retcode = dbo.sp_MSdrop_logreader_agent
  13419.             @publisher = @publisher,
  13420.             @publisher_db = @publisher_db,
  13421.             @publication = @publication
  13422.  
  13423.         IF @@ERROR <> 0 or @retcode <> 0
  13424.             goto UNDO
  13425.  
  13426.         exec @retcode = dbo.sp_MSadd_logreader_agent
  13427.             @name = @value,
  13428.             @publisher = @publisher,
  13429.             @publisher_db = @publisher_db,
  13430.             @publication = @publication,
  13431.             @local_job = 0
  13432.  
  13433.         IF @@ERROR <> 0 or @retcode <> 0
  13434.             goto UNDO
  13435.     END
  13436.     ELSE if LOWER(@property) IN ('retention')
  13437.     BEGIN
  13438.         select @retention_value = convert(int, @value)
  13439.         select @publication_type = publication_type
  13440.             from MSpublications
  13441.             WHERE   publisher_id = @publisher_id AND
  13442.                     publisher_db = @publisher_db AND
  13443.                     publication = @publication
  13444.         UPDATE MSpublications set retention=@retention_value 
  13445.         WHERE   publisher_id = @publisher_id AND
  13446.                     publisher_db = @publisher_db AND
  13447.                     publication = @publication
  13448.         if @@ERROR<>0
  13449.                 goto UNDO
  13450.     END
  13451.     ELSE
  13452.     BEGIN
  13453.         SELECT @cmd = ''
  13454.         SELECT @cmd = @cmd + 'UPDATE MSpublications '
  13455.         SELECT @cmd = @cmd + '   SET ' + LOWER(@property) + ' = '
  13456.         /* @value can be 255 nchars, so don't append it */
  13457.         SELECT @cmd2 = ' WHERE publisher_id = ' + STR(@publisher_id)
  13458.         SELECT @cmd2 =  @cmd2 + ' AND publisher_db = ' + '''' + @publisher_db + ''''
  13459.         SELECT @cmd2 =  @cmd2 + ' AND publication = ' + '''' + @publication + ''''
  13460.         EXECUTE (@cmd + @value + @cmd2)
  13461.         IF @@ERROR <> 0 
  13462.             goto UNDO
  13463.     END
  13464.  
  13465.     COMMIT TRAN
  13466.  
  13467.     RETURN(0)
  13468.  
  13469. UNDO:
  13470.     IF @@TRANCOUNT = 1
  13471.         ROLLBACK TRAN
  13472.     ELSE
  13473.         COMMIT TRAN   
  13474.     RETURN (1)
  13475. go
  13476.  
  13477.  
  13478. raiserror(15339,-1,-1,'sp_MSadd_article')
  13479. go
  13480. CREATE PROCEDURE sp_MSadd_article
  13481. @publisher sysname,
  13482. @publisher_db sysname,
  13483. @publication sysname,
  13484. @article sysname,
  13485. @article_id int = NULL,
  13486. @destination_object sysname = NULL,
  13487. @source_object sysname = NULL,
  13488. @description nvarchar(255) = NULL,
  13489. @source_owner   sysname = NULL
  13490. as
  13491.  
  13492.     set nocount on
  13493.  
  13494.     declare @publisher_id smallint
  13495.     declare @publication_id int
  13496.     declare @retcode int
  13497.     declare @thirdparty_flag bit
  13498.     declare @immediate_sync bit
  13499.     declare @allow_anonymous bit
  13500.     declare @subscription_seqno binary(16)
  13501.     declare @status tinyint
  13502.     declare @subscribed tinyint
  13503.     declare @active tinyint
  13504.  
  13505.     select @subscribed = 1  
  13506.     select @active = 2
  13507.         
  13508.     -- Check if publisher is a defined as a distribution publisher in the current database
  13509.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  13510.     if @retcode <> 0
  13511.     begin
  13512.         return(1)
  13513.     end
  13514.  
  13515.     -- Get publication id
  13516.     select @publication_id = publication_id,  
  13517.         @thirdparty_flag = thirdparty_flag,
  13518.         @immediate_sync = immediate_sync, @allow_anonymous = allow_anonymous 
  13519.         from MSpublications where
  13520.         publisher_id = @publisher_id and 
  13521.         publisher_db = @publisher_db and
  13522.         publication = @publication
  13523.     if @publication_id is NULL
  13524.     begin
  13525.         raiserror (20026, 11, -1, @publication)
  13526.         return (1)
  13527.     end
  13528.  
  13529.     -- Make sure article does not already exist
  13530.     if exists (select * from MSarticles where publication_id = @publication_id and
  13531.         publisher_id = @publisher_id and publisher_db = @publisher_db and article = @article)
  13532.     begin
  13533.         if @thirdparty_flag = 1
  13534.         begin
  13535.             raiserror (14030, 16, -1, @article, @publication)
  13536.             return (1)
  13537.         end
  13538.         else
  13539.         begin
  13540.             exec @retcode = dbo.sp_MSdrop_article
  13541.                 @publisher = @publisher,
  13542.                 @publisher_db = @publisher_db,
  13543.                 @publication = @publication,
  13544.                 @article = @article
  13545.             if @retcode <> 0 or @@error <> 0
  13546.             begin
  13547.                 return (1)
  13548.             end
  13549.         end
  13550.     end
  13551.  
  13552.     -- If it is a third party publication - check if a subscription exists
  13553.     -- for the publication already. If it does then we cannot add any
  13554.     -- articles - the existing subscriptions will have to dropped first and then
  13555.     -- resubscribed
  13556.     if (@thirdparty_flag = 1)
  13557.     begin
  13558.         if exists (select * from MSsubscriptions where 
  13559.                 publisher_id = @publisher_id and 
  13560.                 publisher_db = @publisher_db and 
  13561.                 publication_id = @publication_id)
  13562.         begin
  13563.             raiserror(21131, 16, -1, @publication)
  13564.             return (1)
  13565.         end
  13566.     end
  13567.  
  13568.     begin tran
  13569.     save tran MSadd_article
  13570.  
  13571.     -- Generate new article id when one is not provided by a 
  13572.     -- third party publisher or merge publication
  13573.     if @article_id is NULL
  13574.     begin
  13575.         if (@thirdparty_flag = 1)
  13576.         begin
  13577.             -- Generate unique id per publisher
  13578.             select @article_id = max(article_id) + 1 from MSarticles where 
  13579.                 publisher_id = @publisher_id
  13580.         end
  13581.         else
  13582.         begin
  13583.             -- 6.5 behavior : retain for compatibility
  13584.             -- NOTE: article_id is incremented per publisher/publisher_db/publication
  13585.             select @article_id = max(article_id) + 1 from MSarticles where 
  13586.                 publisher_id = @publisher_id and
  13587.                 publisher_db = @publisher_db and
  13588.                 publication_id = @publication_id
  13589.         end
  13590.  
  13591.         if @article_id is null
  13592.             select @article_id = 1
  13593.     end
  13594.  
  13595.     insert into MSarticles values (@publisher_id, @publisher_db, @publication_id,
  13596.         @article, @article_id, @destination_object, @source_owner, @source_object, @description)
  13597.     if @@error <> 0
  13598.     begin
  13599.         if @@trancount > 0
  13600.         begin
  13601.             rollback tran MSadd_article
  13602.             commit tran
  13603.         end
  13604.         return (1)
  13605.     end
  13606.  
  13607.     -- For third party publications create immediate sync and anonymous virtual subscription
  13608.     -- with 'subscribed' status and then change anonymous virtual to 'active' status
  13609.     -- SQL Server publications will do this via RPC calls to sp_MSadd_subscription
  13610.     if @thirdparty_flag = 1 
  13611.     begin
  13612.         select @subscription_seqno = 0x00  
  13613.         if @immediate_sync = 1
  13614.         begin
  13615.             if @allow_anonymous = 1
  13616.                 select @status = @active
  13617.             else
  13618.                 select @status = @subscribed
  13619.             exec @retcode = dbo.sp_MSadd_subscription
  13620.                 @publisher = @publisher,
  13621.                 @publisher_db = @publisher_db,
  13622.                 @publication = @publication,
  13623.                 @article_id = @article_id,
  13624.                 @subscriber = NULL,                 -- virtual subscription
  13625.                 @status = @status,              
  13626.                 @subscription_seqno = @subscription_seqno,
  13627.                 @sync_type = 1  -- virtual subscriptions are automatic sync type 
  13628.             if @retcode <> 0 or @@error <> 0
  13629.             begin
  13630.                 if @@trancount > 0
  13631.                 begin
  13632.                     rollback tran MSadd_article
  13633.                     commit tran
  13634.                 end
  13635.                 return (1)
  13636.             end
  13637.         end
  13638.     end
  13639.  
  13640.     commit tran
  13641. go
  13642.  
  13643. raiserror(15339,-1,-1,'sp_MSchange_article')
  13644. go
  13645. CREATE PROCEDURE sp_MSchange_article
  13646. @publisher sysname,
  13647. @publisher_db sysname,
  13648. @publication sysname,
  13649. @article sysname,
  13650. @article_id int,
  13651. @property nvarchar(20) = NULL,
  13652. @value nvarchar(255) = NULL
  13653. AS
  13654.     DECLARE @retcode int
  13655.     DECLARE @publisher_id smallint
  13656.     DECLARE @publication_id int
  13657.  
  13658.     -- Get publisher id
  13659.  
  13660.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  13661.     if @retcode <> 0
  13662.     begin
  13663.         return(1)
  13664.     end
  13665.  
  13666.     -- Get publication id
  13667.  
  13668.     select @publication_id = publication_id
  13669.         from MSpublications where
  13670.         publisher_id = @publisher_id and 
  13671.         publisher_db = @publisher_db and
  13672.         publication = @publication
  13673.     if @publication_id is NULL
  13674.     begin
  13675.         raiserror (20026, 11, -1, @publication)
  13676.         return (1)
  13677.     end
  13678.  
  13679.     if @property = N'description'     
  13680.     begin
  13681.         update MSarticles set description = @value
  13682.         where publisher_id = @publisher_id
  13683.         and publisher_db = @publisher_db
  13684.         and publication_id = @publication_id
  13685.         and article = @article
  13686.         and article_id = @article_id
  13687.         if @@error <> 0
  13688.         begin
  13689.             return 1
  13690.         end
  13691.     end
  13692.     else if @property in( N'dest_table', N'dest_object' )
  13693.     begin
  13694.         update MSarticles set destination_object = @value
  13695.         where publisher_id = @publisher_id
  13696.         and publisher_db = @publisher_db
  13697.         and publication_id = @publication_id
  13698.         and article = @article
  13699.         and article_id = @article_id
  13700.         if @@error <> 0
  13701.         begin
  13702.             return 1
  13703.         end
  13704.     end
  13705.     else
  13706.     begin
  13707.         return 1
  13708.     end
  13709. go
  13710.  
  13711.  
  13712. raiserror(15339,-1,-1,'sp_MShelp_publication')
  13713. go   
  13714. CREATE PROCEDURE sp_MShelp_publication 
  13715. @publisher sysname,
  13716. @publisher_db sysname = '%',
  13717. @publication sysname = '%'
  13718.  
  13719. as
  13720.  
  13721.     set nocount on
  13722.  
  13723.     if @publisher_db != '%' and @publication != '%' and not exists (select * from MSpublications where
  13724.         publisher_id = (select srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)) and
  13725.         publisher_db like @publisher_db and
  13726.         publication like @publication)
  13727.     begin
  13728.         raiserror(20026, 16, -1, @publication)
  13729.         return(1)
  13730.     end
  13731.  
  13732.     select p.publisher_db, p.publication, p.publication_id, p.publication_type, 
  13733.         --thirdparty_flag, 
  13734.         independent_agent,
  13735.         immediate_sync, allow_push, allow_pull, allow_anonymous, 'snapshot_agent' = s.name,
  13736.         'logreader_agent' = l.name, description, vendor_name
  13737.         from MSpublications p  
  13738.         LEFT OUTER JOIN MSsnapshot_agents s
  13739.         ON
  13740.         s.publisher_id = p.publisher_id and
  13741.         s.publisher_db = p.publisher_db and
  13742.         s.publication = p.publication
  13743.         LEFT OUTER JOIN MSlogreader_agents l
  13744.         ON
  13745.         (l.publisher_id = p.publisher_id and
  13746.         l.publisher_db = p.publisher_db and
  13747.         p.publication_type = 0 and              -- Only Transactional Publication has a  Log Reader
  13748.         (l.publication = p.publication OR
  13749.          thirdparty_flag = 0))
  13750.         where 
  13751.         p.publisher_id = (select srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)) and
  13752.         p.publisher_db like @publisher_db and
  13753.         p.publication like @publication 
  13754. go
  13755.  
  13756. raiserror(15339,-1,-1,'sp_MShelp_article')
  13757. go
  13758. CREATE PROCEDURE sp_MShelp_article 
  13759. @publisher sysname,
  13760. @publisher_db sysname,
  13761. @publication sysname,        
  13762. @article sysname = '%'
  13763. as
  13764.  
  13765.     set nocount on
  13766.  
  13767.     select article, article_id, source_object, description, source_owner from MSarticles a where 
  13768.         a.publisher_id = (select srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)) and 
  13769.         a.publisher_db = @publisher_db and
  13770.         a.publication_id = (select publication_id from MSpublications where 
  13771.             publisher_id = a.publisher_id and
  13772.             publisher_db = a.publisher_db and
  13773.             publication = @publication) and
  13774.         a.article like @article
  13775. go
  13776.  
  13777. raiserror(15339,-1,-1,'sp_MShelp_subscription')
  13778. go
  13779. CREATE PROCEDURE sp_MShelp_subscription 
  13780. @publisher sysname,
  13781. @publisher_db sysname,
  13782. @publication sysname,        
  13783. @subscriber sysname = '%',              
  13784. @subscriber_db sysname = '%'
  13785. as
  13786. set nocount on
  13787.  
  13788.     select distinct ss.srvname + ':' + s.subscriber_db, ss.srvname, s.subscriber_db, s.subscription_type, 
  13789.         sync_type, status, agent.name from 
  13790.         MSsubscriptions s, master..sysservers ss, MSdistribution_agents agent where 
  13791.         s.publisher_id = (select srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)) and 
  13792.         s.publisher_db = @publisher_db and
  13793.         s.publication_id = (select publication_id from MSpublications where 
  13794.             publisher_id = s.publisher_id and
  13795.             publisher_db = s.publisher_db and
  13796.             publication = @publication) and
  13797.         s.subscriber_db like @subscriber_db and
  13798.         s.subscriber_id = ss.srvid and
  13799.         ((@subscriber = N'%') or (ss.srvname = @subscriber)) and
  13800.         s.subscriber_id >= 0 and                    -- ignore virtual subscriptions
  13801.         s.agent_id = agent.id
  13802. go
  13803.  
  13804. raiserror(15339,-1,-1,'sp_MSadd_subscription_3rd')
  13805. go
  13806. CREATE PROCEDURE sp_MSadd_subscription_3rd
  13807. @publisher sysname,
  13808. @publisher_db sysname,
  13809. @publication sysname,
  13810. @subscriber sysname,       
  13811. @subscriber_db sysname = NULL,
  13812. @status tinyint,                    -- 0 = inactive, 1 = subscribed, 2 = active 
  13813. @subscription_type tinyint = 0,     -- 0 = push, 1 = pull, 2 = anonymous 
  13814. @sync_type tinyint = 2,             -- 0 = none  1 = automatic snaphot  2 = no intial snapshot
  13815.  
  13816. @frequency_type int = NULL,
  13817. @frequency_interval int = NULL,
  13818. @frequency_relative_interval int = NULL,
  13819. @frequency_recurrence_factor int = NULL,
  13820. @frequency_subday int = NULL,
  13821. @frequency_subday_interval int = NULL,
  13822. @active_start_time_of_day int = NULL,
  13823. @active_end_time_of_day int = NULL,
  13824. @active_start_date int = NULL,
  13825. @active_end_date int = NULL,
  13826.  
  13827. @distribution_jobid binary(8) = NULL OUTPUT
  13828.  
  13829. as
  13830.     set nocount on
  13831.  
  13832.     declare @retcode int
  13833.     declare @publication_id int
  13834.     declare @article_id int
  13835.     declare @virtual_id smallint
  13836.     declare @publisher_id smallint
  13837.     declare @immediate_sync bit
  13838.     declare @allow_push bit
  13839.     declare @allow_pull bit
  13840.     declare @allow_anonymous bit
  13841.     declare @subscription_seqno binary(16)
  13842.  
  13843.     select @virtual_id = -1
  13844.  
  13845.     -- Check if publisher is a defined as a distribution publisher in the current database
  13846.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  13847.     if @retcode <> 0
  13848.     begin
  13849.         return(1)
  13850.     end
  13851.  
  13852.     -- Get publication information
  13853.     select @publication_id = publication_id, @immediate_sync = immediate_sync,
  13854.         @allow_push = allow_push, @allow_pull = allow_pull, @allow_anonymous = allow_anonymous
  13855.         from MSpublications where
  13856.         publisher_id = @publisher_id and
  13857.         publisher_db = @publisher_db and
  13858.         publication = @publication
  13859.     if @publication_id is null
  13860.     begin
  13861.         raiserror(14016, 16, -1, @publication)
  13862.         return (1)
  13863.     end
  13864.  
  13865.     -- Check if publication supports subscription type
  13866.     if @subscription_type = 0 and @allow_push != 1
  13867.     begin
  13868.         raiserror(20034, 16, -1, @publication, 'push')
  13869.         return (1)
  13870.     end
  13871.     else if @subscription_type = 1 and @allow_pull != 1
  13872.     begin
  13873.         raiserror(20034, 16, -1, @publication, 'pull')
  13874.         return (1)
  13875.     end
  13876.     else if @subscription_type = 2 and @allow_anonymous != 1
  13877.     begin
  13878.         raiserror(20034, 16, -1, @publication, 'anonymous')
  13879.         return (1)
  13880.     end
  13881.  
  13882.     begin tran
  13883.     save tran MSadd_subscription_3rd
  13884.  
  13885.     -- Add a subscription for each article in the publication
  13886.     declare hCMSadd_subscription_3rd CURSOR LOCAL FAST_FORWARD FOR 
  13887.         select article_id from MSarticles a where
  13888.             a.publisher_id = @publisher_id and
  13889.             a.publisher_db = @publisher_db and
  13890.             a.publication_id = @publication_id
  13891.         for read only
  13892.  
  13893.     open hCMSadd_subscription_3rd
  13894.     fetch hCMSadd_subscription_3rd into @article_id
  13895.         
  13896.     while (@@fetch_status <> -1)
  13897.     begin
  13898.         if @immediate_sync = 1
  13899.             select @subscription_seqno = subscription_seqno from MSsubscriptions where
  13900.                 publisher_id = @publisher_id and
  13901.                 publisher_db = @publisher_db and
  13902.                 article_id = @article_id and
  13903.                 subscriber_id = @virtual_id 
  13904.         else
  13905.             select @subscription_seqno = 0x00 --BUG need to convert
  13906.  
  13907.         exec @retcode = dbo.sp_MSadd_subscription
  13908.             @publisher = @publisher,
  13909.             @publisher_db = @publisher_db,
  13910.             @publication = @publication,        -- Must provide this
  13911.             @article_id = @article_id,
  13912.             @subscriber = @subscriber,       
  13913.             @subscriber_db = @subscriber_db,
  13914.             @status = @status,
  13915.             @subscription_seqno = @subscription_seqno,
  13916.             @subscription_type = @subscription_type,
  13917.             @sync_type = @sync_type,
  13918.  
  13919.             @frequency_type = @frequency_type,
  13920.             @frequency_interval = @frequency_interval,
  13921.             @frequency_relative_interval = @frequency_relative_interval,
  13922.             @frequency_recurrence_factor = @frequency_recurrence_factor,
  13923.             @frequency_subday = @frequency_subday,
  13924.             @frequency_subday_interval = @frequency_subday_interval,
  13925.             @active_start_time_of_day = @active_start_time_of_day,
  13926.             @active_end_time_of_day = @active_end_time_of_day,
  13927.             @active_start_date = @active_start_date,
  13928.             @active_end_date = @active_end_date,
  13929.  
  13930.             @distribution_jobid = @distribution_jobid output
  13931.         if @retcode != 0 or @@error != 0
  13932.         begin
  13933.             close hCMSadd_subscription_3rd
  13934.             deallocate hCMSadd_subscription_3rd
  13935.             if @@trancount > 0
  13936.             begin
  13937.                 rollback tran MSadd_subscription_3rd
  13938.                 commit tran
  13939.             end
  13940.             return(1)
  13941.         end
  13942.  
  13943.         fetch hCMSadd_subscription_3rd into @article_id
  13944.     end
  13945.  
  13946.     close hCMSadd_subscription_3rd
  13947.     deallocate hCMSadd_subscription_3rd
  13948.  
  13949.     -- If article_id is null, there were no articles defined for the publication
  13950.     if @article_id is NULL
  13951.     begin
  13952.         raiserror(14009, 16, -1, @publication)
  13953.         if @@trancount > 0
  13954.         begin
  13955.             rollback tran MSadd_subscription_3rd
  13956.             commit tran
  13957.         end
  13958.         return (1)
  13959.     end
  13960.  
  13961.     commit tran
  13962.  
  13963. go
  13964.  
  13965. raiserror(15339,-1,-1,'sp_MSdrop_subscription_3rd')
  13966. go
  13967. CREATE PROCEDURE sp_MSdrop_subscription_3rd
  13968. @publisher sysname,
  13969. @publisher_db sysname,
  13970. @publication sysname,
  13971. @subscriber sysname,       
  13972. @subscriber_db sysname = NULL
  13973.  
  13974. as
  13975.     set nocount on
  13976.  
  13977.     declare @retcode int
  13978.     declare @article_id int
  13979.     declare @publisher_id smallint
  13980.     declare @publication_id int
  13981.  
  13982.     -- Check if publisher is a defined as a distribution publisher in the current database
  13983.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  13984.     if @retcode <> 0
  13985.     begin
  13986.         return(1)
  13987.     end
  13988.  
  13989.     -- Get publication information
  13990.     select @publication_id = publication_id from MSpublications where
  13991.         publisher_id = @publisher_id and
  13992.         publisher_db = @publisher_db and
  13993.         publication = @publication
  13994.     if @publication_id is null
  13995.     begin
  13996.         raiserror(14016, 16, -1, @publication)
  13997.         return (1)
  13998.     end
  13999.  
  14000.     begin tran
  14001.     save tran MSdrop_subscription_3rd
  14002.  
  14003.     -- Drop the subscription for each article in the publication
  14004.     if lower(@subscriber) = 'all' and lower(@subscriber_db) = 'all'
  14005.     begin
  14006.         declare hCMSdrop_subscription_3rd CURSOR LOCAL FAST_FORWARD FOR 
  14007.             select a.article_id, srv.srvname, sub.subscriber_db 
  14008.                 from MSarticles a, MSsubscriptions sub, master..sysservers srv where
  14009.                 a.publisher_id = @publisher_id and
  14010.                 a.publisher_db = @publisher_db and
  14011.                 a.publication_id = @publication_id and
  14012.                 sub.article_id = a.article_id and
  14013.                 sub.publisher_id = @publisher_id and
  14014.                 sub.publisher_db = @publisher_db and
  14015.                 sub.publication_id = @publication_id and
  14016.                 srv.srvid = sub.subscriber_id and
  14017.                 sub.subscriber_id >= 0
  14018.             union
  14019.             -- For virtual subscriptions
  14020.             select a.article_id, convert(sysname, null), convert(sysname, null)
  14021.                 from MSarticles a where
  14022.                 a.publisher_id = @publisher_id and
  14023.                 a.publisher_db = @publisher_db and
  14024.                 a.publication_id = @publication_id and
  14025.                 exists (select * from MSsubscriptions sub where
  14026.                     sub.article_id = a.article_id and
  14027.                     sub.publisher_id = @publisher_id and
  14028.                     sub.publisher_db = @publisher_db and
  14029.                     sub.publication_id = @publication_id and
  14030.                     sub.subscriber_id <0 )
  14031.             for read only
  14032.     end
  14033.     else
  14034.         declare hCMSdrop_subscription_3rd CURSOR LOCAL FAST_FORWARD FOR 
  14035.             select article_id, @subscriber, @subscriber_db from MSarticles a where
  14036.                 a.publisher_id = @publisher_id and
  14037.                 a.publisher_db = @publisher_db and
  14038.                 a.publication_id = @publication_id
  14039.             for read only
  14040.  
  14041.     open hCMSdrop_subscription_3rd
  14042.     fetch hCMSdrop_subscription_3rd into @article_id, @subscriber, @subscriber_db
  14043.         
  14044.     while (@@fetch_status <> -1)
  14045.     begin
  14046.         exec @retcode = dbo.sp_MSdrop_subscription
  14047.             @publisher = @publisher,
  14048.             @publisher_db = @publisher_db,
  14049.             @publication = @publication,        -- Must provide this
  14050.             @article_id = @article_id,
  14051.             @subscriber = @subscriber,       
  14052.             @subscriber_db = @subscriber_db
  14053.         if @retcode != 0 or @@error != 0
  14054.         begin
  14055.             close hCMSdrop_subscription_3rd
  14056.             deallocate hCMSdrop_subscription_3rd
  14057.             if @@trancount > 0
  14058.             begin
  14059.                 rollback tran MSdrop_subscription_3rd
  14060.                 commit tran
  14061.             end
  14062.             return (1)
  14063.         end
  14064.  
  14065.        fetch hCMSdrop_subscription_3rd into @article_id, @subscriber, @subscriber_db
  14066.     end
  14067.  
  14068.     close hCMSdrop_subscription_3rd
  14069.     deallocate hCMSdrop_subscription_3rd
  14070.     commit tran
  14071. go
  14072.  
  14073. raiserror(15339,-1,-1,'sp_MSactivate_subscriptions')
  14074. go
  14075.  
  14076. CREATE PROCEDURE sp_MSactivate_subscriptions
  14077. @publisher_id int,
  14078. @publisher_db sysname,
  14079. @publication_id int, 
  14080. @xact_seqno varbinary(16),
  14081. @reset bit = 0      /* @reset = 1 is used for Scheduled Snapshot publications by snapshot */
  14082. AS
  14083.  
  14084.     declare @article_id int
  14085.     declare @retcode int
  14086.  
  14087.     declare hCseqno_3rd CURSOR LOCAL FAST_FORWARD FOR 
  14088.         select article_id from MSarticles a where
  14089.             a.publisher_id = @publisher_id and
  14090.             a.publisher_db = @publisher_db and
  14091.             a.publication_id = @publication_id
  14092.         for read only
  14093.  
  14094.     open hCseqno_3rd
  14095.     fetch hCseqno_3rd into @article_id
  14096.         
  14097.     while (@@fetch_status <> -1)
  14098.     begin
  14099.         select @article_id
  14100.         select @xact_seqno
  14101.         exec @retcode = dbo.sp_MSset_snapshot_xact_seqno
  14102.             @publisher_id = @publisher_id,
  14103.             @publisher_db = @publisher_db,
  14104.             @article_id = @article_id,
  14105.             @xact_seqno = @xact_seqno,
  14106.             @reset = @reset
  14107.         if @retcode != 0 or @@error != 0
  14108.         begin
  14109.             close hCseqno_3rd
  14110.             deallocate hCseqno_3rd
  14111.             return(1)
  14112.         end
  14113.  
  14114.         -- Activate the subscriptions
  14115.         exec @retcode = dbo.sp_MSdist_activate_auto_sub
  14116.             @publisher_id = @publisher_id,
  14117.             @publisher_db = @publisher_db,
  14118.             @article_id = @article_id
  14119.         if @retcode != 0 or @@error != 0
  14120.         begin
  14121.             close hCseqno_3rd
  14122.             deallocate hCseqno_3rd
  14123.             return(1)
  14124.         end
  14125.  
  14126.         fetch hCseqno_3rd into @article_id
  14127.     end
  14128.  
  14129.     close hCseqno_3rd
  14130.     deallocate hCseqno_3rd
  14131. GO
  14132. raiserror(15339,-1,-1,'sp_MSdrop_merge_subscription')
  14133. GO
  14134.  
  14135. CREATE PROCEDURE sp_MSdrop_merge_subscription
  14136. @publisher          sysname,
  14137. @publisher_db       sysname,
  14138. @publication        sysname,
  14139. @subscriber         sysname,
  14140. @subscriber_db      sysname,
  14141. @subscription_type  nvarchar(15) = 'push'           /* Subscription type - push, pull, both */ 
  14142.  
  14143. as
  14144.  
  14145.     set nocount on
  14146.  
  14147.     declare @publisher_id smallint
  14148.     declare @subscriber_id smallint
  14149.     declare @retcode int
  14150.     declare @publication_id int
  14151.     declare @job_id binary(16)
  14152.     declare @thirdparty_flag bit
  14153.     declare @id                 int
  14154.     declare @keep_for_last_run  bit
  14155.  
  14156.     -- Check if publisher is a defined as a distribution publisher in the current database
  14157.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  14158.     if @retcode <> 0
  14159.     begin
  14160.         return(1)
  14161.     end
  14162.  
  14163.     -- Check if subscriber exists
  14164.     select @subscriber_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber) 
  14165.     if @subscriber_id is NULL
  14166.     begin
  14167.         raiserror (20032, 16, -1, @subscriber, @publisher) 
  14168.         return (1)
  14169.     end
  14170.  
  14171.     -- Check if the publication exists
  14172.     select @publication_id = publication_id,
  14173.         @thirdparty_flag = thirdparty_flag
  14174.         from MSpublications where
  14175.         publisher_id = @publisher_id and
  14176.         publisher_db = @publisher_db and
  14177.         publication = @publication
  14178.     if @publication_id is NULL
  14179.     begin
  14180.         raiserror (20026, 16, -1, @publication) 
  14181.        return (1)
  14182.     end
  14183.  
  14184.     -- Check that subscription exists
  14185.     if not exists (select * from MSmerge_subscriptions where 
  14186.         publisher_id = @publisher_id and 
  14187.         publisher_db = @publisher_db and 
  14188.         publication_id = @publication_id and
  14189.         subscriber_id = @subscriber_id and
  14190.         subscriber_db = @subscriber_db)
  14191.     begin
  14192.         if @thirdparty_flag = 1
  14193.         begin
  14194.             --UNDONE : Add this back again when we add pull subscriptions metedata at the distributor
  14195.             --raiserror (14050, 10, -1)
  14196.             return(1)
  14197.         end
  14198.         else
  14199.             return (0)
  14200.     end
  14201.  
  14202.     begin tran
  14203.     save transaction MSdrop_merge_subscription
  14204.  
  14205.     -- Delete the subscription 
  14206.     -- For anonymous type, delete virtual anonymous subscription also
  14207.     -- if deleting the  virtual subscription 
  14208.     -- (since there can be only one subscriber_id per article, subscriber_db doesn't matter)
  14209.     delete from MSmerge_subscriptions where
  14210.         publisher_id = @publisher_id and
  14211.         publisher_db = @publisher_db and
  14212.         publication_id = @publication_id and
  14213.         subscriber_id = @subscriber_id and
  14214.         subscriber_db = @subscriber_db
  14215.     if @@error <> 0
  14216.     begin
  14217.         goto FAILURE
  14218.     end
  14219.  
  14220.     /*
  14221.     ** Get agentid to check history record
  14222.     */
  14223.     select @id=id from MSmerge_agents where 
  14224.         publisher_id = @publisher_id and
  14225.         publisher_db = @publisher_db and
  14226.         publication = @publication and
  14227.         subscriber_id = @subscriber_id and
  14228.         subscriber_db = @subscriber_db
  14229.  
  14230.     /*
  14231.     ** If the subscription has not yet been synced, there is no need for subscriber side cleanup 
  14232.     ** therefore no need for the last agent run.
  14233.     */
  14234.     if exists (select * from MSmerge_history where agent_id = @id) and @subscription_type='push'
  14235.         select @keep_for_last_run = 0 -- cleanup code is not activated.
  14236.     else 
  14237.         select @keep_for_last_run = 0
  14238.     
  14239.     /*
  14240.     ** Delete Merge agent and meta data, if it exists
  14241.     */
  14242.     EXECUTE @retcode = dbo.sp_MSdrop_merge_agent 
  14243.         @publisher = @publisher,
  14244.         @publisher_db = @publisher_db,
  14245.         @publication = @publication,
  14246.         @subscriber = @subscriber,
  14247.         @subscriber_db = @subscriber_db,
  14248.         @keep_for_last_run = @keep_for_last_run
  14249.     if @@error <> 0 or @retcode <> 0
  14250.     begin
  14251.         goto FAILURE
  14252.     end
  14253.  
  14254.     commit transaction
  14255.     return 0
  14256. FAILURE:
  14257.     if @@trancount > 0
  14258.     begin   
  14259.         ROLLBACK TRANSACTION MSdrop_merge_subscription
  14260.         COMMIT TRANSACTION
  14261.     end
  14262.     return 1
  14263.         
  14264. GO
  14265.  
  14266. raiserror(15339,-1,-1,'sp_MSadd_merge_subscription')
  14267. GO
  14268. CREATE PROCEDURE sp_MSadd_merge_subscription
  14269. @publisher sysname,
  14270. @publisher_db sysname,
  14271. @publication sysname,
  14272. @subscriber sysname,       
  14273. @subscriber_db sysname,
  14274. @subscription_type tinyint = 0,     -- 0 = push, 1 = pull
  14275. @sync_type tinyint = 1,             -- 0 = none  1 = automatic snaphot  2 = no intial snapshot
  14276. @status tinyint = 1,                -- 0 = inactive, 1 = subscribed, 2 = active 
  14277. @frequency_type int = NULL,
  14278. @frequency_interval int = NULL,
  14279. @frequency_relative_interval int = NULL,
  14280. @frequency_recurrence_factor int = NULL,
  14281. @frequency_subday int = NULL,
  14282. @frequency_subday_interval int = NULL,
  14283. @active_start_time_of_day int = NULL,
  14284. @active_end_time_of_day int = NULL,
  14285. @active_start_date int = NULL,
  14286. @active_end_date int = NULL,
  14287. @optional_command_line nvarchar(4000) = NULL,
  14288. @agent_name nvarchar(100) = NULL,
  14289. @merge_jobid binary(16) = NULL OUTPUT
  14290. as
  14291.  
  14292.     set nocount on
  14293.  
  14294.     declare @publisher_id smallint
  14295.     declare @subscriber_id smallint
  14296.     declare @publication_id int
  14297.     declare @retcode int
  14298.  
  14299.     -- default values 
  14300.     declare @flushfrequency int 
  14301.     declare @frequencytype int
  14302.     declare @frequencyinterval int 
  14303.     declare @frequencyrelativeinterval int
  14304.     declare @frequencyrecurrencefactor int 
  14305.     declare @frequencysubday int 
  14306.     declare @frequencysubdayinterval int
  14307.     declare @activestarttimeofday int
  14308.     declare @activeendtimeofday int
  14309.     declare @activestartdate int 
  14310.     declare @activeenddate int 
  14311.     declare @push int
  14312.     declare @local_job bit
  14313.     declare @thirdparty_flag bit
  14314.  
  14315.     select @push = 0
  14316.  
  14317.     -- Check if publisher is a defined as a distribution publisher in the current database
  14318.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  14319.     if @retcode <> 0
  14320.     begin
  14321.         return(1)
  14322.     end
  14323.  
  14324.     -- Get the publication information 
  14325.     select @publication_id = publication_id,
  14326.         @thirdparty_flag = thirdparty_flag from 
  14327.         MSpublications where 
  14328.         publisher_id = @publisher_id and
  14329.         publisher_db = @publisher_db and
  14330.         publication = @publication
  14331.     if @publication_id is NULL
  14332.     begin
  14333.         raiserror (20026, 11, -1, @publication)
  14334.         return (1)
  14335.     end
  14336.  
  14337.     -- Get subscriber info
  14338.     select @subscriber_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  14339.  
  14340.     -- Make sure subscription does not already exist
  14341.     if exists (select * from MSmerge_subscriptions where 
  14342.         publisher_id = @publisher_id and 
  14343.         publisher_db = @publisher_db and 
  14344.         publication_id = @publication_id and
  14345.         subscriber_id = @subscriber_id and
  14346.         subscriber_db = @subscriber_db)
  14347.     begin
  14348.         if @thirdparty_flag = 1
  14349.         begin
  14350.             raiserror (14058, 16, -1)
  14351.             return(1)
  14352.         end
  14353.         else
  14354.         begin
  14355.             exec @retcode = dbo.sp_MSdrop_merge_subscription 
  14356.                 @publisher = @publisher,
  14357.                 @publisher_db = @publisher_db,
  14358.                 @publication = @publication,
  14359.                 @subscriber = @subscriber,
  14360.                 @subscriber_db = @subscriber_db,
  14361.                 @subscription_type  = @subscription_type
  14362.             if @retcode <> 0 or @@error <> 0
  14363.             begin
  14364.                 return (1)
  14365.             end
  14366.         end
  14367.     end
  14368.  
  14369.     --Get default task parameter values from MSsubscriber_info 
  14370.     --BUG currently using the same values used for transactional publications
  14371.     -- BUG FIXED
  14372.     
  14373.     select @frequencytype = frequency_type,
  14374.         @frequencyinterval = frequency_interval,
  14375.         @frequencyrelativeinterval = frequency_relative_interval,
  14376.         @frequencyrecurrencefactor = frequency_recurrence_factor,
  14377.         @frequencysubday = frequency_subday,
  14378.         @frequencysubdayinterval = frequency_subday_interval,
  14379.         @activestarttimeofday = active_start_time_of_day,
  14380.         @activeendtimeofday = active_end_time_of_day,
  14381.         @activestartdate = active_start_date,
  14382.         @activeenddate = active_end_date
  14383.     from MSsubscriber_schedule 
  14384.     where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 1
  14385.  
  14386.     if @frequency_type is null
  14387.         select @frequency_type = @frequencytype
  14388.  
  14389.     if @frequency_interval  is null
  14390.         select  @frequency_interval = @frequencyinterval
  14391.  
  14392.     if @frequency_relative_interval is null
  14393.         select  @frequency_relative_interval = @frequencyrelativeinterval
  14394.  
  14395.     if @frequency_recurrence_factor is null
  14396.         select  @frequency_recurrence_factor = @frequencyrecurrencefactor
  14397.  
  14398.     if @frequency_subday is null
  14399.         select  @frequency_subday = @frequencysubday
  14400.  
  14401.     if @frequency_subday_interval is null
  14402.         select  @frequency_subday_interval = @frequencysubdayinterval
  14403.  
  14404.     if @active_start_time_of_day is null
  14405.         select  @active_start_time_of_day = @activestarttimeofday
  14406.  
  14407.     if @active_end_time_of_day is null
  14408.         select  @active_end_time_of_day = @activeendtimeofday
  14409.  
  14410.     if @active_start_date is null
  14411.         select  @active_start_date = @activestartdate
  14412.  
  14413.     if @active_end_date is null
  14414.         select  @active_end_date = @activeenddate
  14415.  
  14416.     begin transaction 
  14417.  
  14418.     -- If push and agent name is not passed in, create local job.
  14419.     if @subscription_type = @push AND @agent_name is NULL
  14420.         select @local_job = 1
  14421.     else
  14422.         select @local_job = 0
  14423.  
  14424.     -- Create Merge Agent
  14425.     exec @retcode = dbo.sp_MSadd_merge_agent
  14426.         @name = @agent_name, 
  14427.         @publisher = @publisher,
  14428.         @publisher_db = @publisher_db,
  14429.         @publication = @publication,
  14430.         @subscriber = @subscriber,
  14431.         @subscriber_db = @subscriber_db,
  14432.         @local_job = @local_job,
  14433.         @frequency_type  = @frequency_type,                         
  14434.         @frequency_interval = @frequency_interval, 
  14435.         @frequency_relative_interval = @frequency_relative_interval, 
  14436.         @frequency_recurrence_factor = @frequency_recurrence_factor, 
  14437.         @frequency_subday = @frequency_subday, 
  14438.         @frequency_subday_interval = @frequency_subday_interval,
  14439.         @active_start_time_of_day = @active_start_time_of_day, 
  14440.         @active_end_time_of_day = @active_end_time_of_day,         
  14441.         @active_start_date = @active_start_date, 
  14442.         @active_end_date = @active_end_date,
  14443.         @optional_command_line = @optional_command_line,
  14444.         @merge_jobid = @merge_jobid OUTPUT
  14445.  
  14446.     if @retcode <> 0 or @@error <> 0
  14447.     begin
  14448.         goto FAILURE
  14449.     end
  14450.     
  14451.     insert into MSmerge_subscriptions values (@publisher_id, @publisher_db, @publication_id,
  14452.         @subscriber_id, @subscriber_db, @subscription_type, @sync_type, @status, 
  14453.         getdate())  --BUG need to store GUID?
  14454.     if @@error <> 0
  14455.     begin
  14456.         goto FAILURE
  14457.     end
  14458.  
  14459.     commit transaction
  14460.     return (0)
  14461.  
  14462. FAILURE:
  14463.     /* UNDONE : This code is specific to 6.X nested transaction semantics */
  14464.     if @@TRANCOUNT = 1 
  14465.         ROLLBACK TRANSACTION 
  14466.     else
  14467.         COMMIT TRANSACTION 
  14468.     RETURN (1)
  14469.     
  14470. GO
  14471.  
  14472. raiserror(15339,-1,-1,'sp_MSenum_merge_subscriptions')
  14473. GO
  14474. create procedure sp_MSenum_merge_subscriptions
  14475. @publisher sysname,
  14476. @publisher_db sysname,
  14477. @publication sysname
  14478.  
  14479. as
  14480.  
  14481.     declare @subscriber sysname
  14482.     declare @subscriber_db sysname
  14483.     declare @subscriber_name sysname
  14484.     declare @type int
  14485.     declare @status int
  14486.     declare @agent_name nvarchar(100)
  14487.     declare @subscriber_id smallint
  14488.     declare @publisher_id smallint
  14489.     declare @start_time nvarchar(24)
  14490.     declare @time nvarchar(24)
  14491.     declare @duration int
  14492.     declare @comments nvarchar(255)
  14493.     declare @delivery_rate float
  14494.     declare @error_id int
  14495.     declare @publication_id int
  14496.     declare @publisher_insertcount int
  14497.     declare @publisher_updatecount int
  14498.     declare @publisher_deletecount int
  14499.     declare @publisher_conflictcount int
  14500.     declare @subscriber_insertcount int
  14501.     declare @subscriber_updatecount int
  14502.     declare @subscriber_deletecount int
  14503.     declare @subscriber_conflictcount int
  14504.     declare @job_id binary(16)
  14505.     declare @local_job bit
  14506.     declare @profile_id int
  14507.     declare @agent_id int
  14508.     declare @current_time datetime
  14509.     declare @last_timestamp binary(8)
  14510.  
  14511.     set nocount on
  14512.  
  14513.     set @current_time = getdate()
  14514.  
  14515.     select @publisher_id = srvid from master..sysservers where
  14516.        UPPER(srvname) = UPPER(@publisher)
  14517.  
  14518.     select @publication_id = publication_id from MSpublications  where 
  14519.             publisher_id = @publisher_id and
  14520.             publisher_db = @publisher_db and
  14521.             publication = @publication and
  14522.             publication_type = 2 -- Merge 
  14523.  
  14524.     create table #merge_subscriptions (subscriber sysname NOT NULL,  status int NOT NULL, 
  14525.         subscriber_db sysname NOT NULL, type int NOT NULL, agent_name nvarchar(100) NOT NULL, last_action nvarchar(255) NULL, 
  14526.         action_time nvarchar(24) NULL, start_time nvarchar(24) NULL, duration int NULL, 
  14527.         delivery_rate float NULL,
  14528.         publisher_insertcount int NULL, publisher_updatecount int NULL, publisher_deletecount int NULL,
  14529.         publisher_conficts int NULL, 
  14530.         subscriber_insertcount int NULL, subscriber_updatecount int NULL, subscriber_deletecount int NULL,
  14531.         subscriber_conficts int NULL, error_id int NULL, job_id binary(16) NULL,
  14532.         local_job bit NULL, profile_id int NOT NULL, 
  14533.         agent_id int NOT NULL, last_timestamp binary(8) NOT NULL)
  14534.     
  14535.     -- This is to force all queries to return rows ordered by job_id
  14536.     create unique clustered index ucmerge_subscriptions ON #merge_subscriptions (agent_id)
  14537.  
  14538.     declare hC CURSOR LOCAL FAST_FORWARD FOR select subscriber_id, subscriber_db, name, job_id, local_job, profile_id, id, subscriber_name
  14539.                                 from MSmerge_agents 
  14540.                                  where publisher_id = @publisher_id and publisher_db = @publisher_db and publication = @publication 
  14541.                             for read only
  14542.     open hC
  14543.     fetch hC into  @subscriber_id, @subscriber_db, @agent_name, @job_id, @local_job, @profile_id, @agent_id, @subscriber_name
  14544.     while (@@fetch_status <> -1)
  14545.     begin
  14546.  
  14547.         if @subscriber_name is not NULL 
  14548.             begin
  14549.                 select @subscriber = @subscriber_name
  14550.                 select @subscriber_db = @subscriber_db + '-' + convert(nvarchar(4), @agent_id)
  14551.                 select @type = 2   --anonymous subscription
  14552.             end
  14553.         else
  14554.             begin
  14555.                 select @subscriber = srvname from master..sysservers where srvid=@subscriber_id
  14556.                 select @type = subscription_type from MSmerge_subscriptions 
  14557.                     where publisher_id = @publisher_id and
  14558.                         publisher_db = @publisher_db and
  14559.                         publication_id = @publication_id and
  14560.                         subscriber_id = @subscriber_id and
  14561.                         subscriber_db = @subscriber_db
  14562.             end
  14563.             
  14564.         -- Get the status of the agent
  14565.         select @status = 0 --BUG the below isnullis not working
  14566.         select  @start_time = NULL,
  14567.             @time = NULL, 
  14568.             @duration = NULL, 
  14569.             @comments = NULL,
  14570.             @publisher_insertcount = NULL,
  14571.             @publisher_deletecount = NULL,
  14572.             @publisher_updatecount =  NULL,
  14573.             @publisher_conflictcount =  NULL,
  14574.             @subscriber_insertcount = NULL,
  14575.             @subscriber_deletecount = NULL,
  14576.             @subscriber_updatecount =  NULL,
  14577.             @subscriber_conflictcount =  NULL,
  14578.             @delivery_rate = NULL, 
  14579.             @error_id = NULL,
  14580.             @last_timestamp = 0x00000000
  14581.                 
  14582.         select @status = isnull(runstatus,0),
  14583.             @start_time = convert(nvarchar(12), start_time, 112) +
  14584.                           substring(convert(nvarchar(24), start_time, 121), 11, 13),
  14585.             @time = convert(nvarchar(12), time, 112) +
  14586.                     substring(convert(nvarchar(24), time, 121), 11, 13), 
  14587.             @duration = DATEDIFF(second, start_time, @current_time), 
  14588.             @comments = comments,
  14589.             @publisher_insertcount = publisher_insertcount,
  14590.             @publisher_deletecount = publisher_deletecount,
  14591.             @publisher_updatecount =  publisher_updatecount,
  14592.             @publisher_conflictcount =  publisher_conflictcount,
  14593.             @subscriber_insertcount = subscriber_insertcount,
  14594.             @subscriber_deletecount = subscriber_deletecount,
  14595.             @subscriber_updatecount =  subscriber_updatecount,
  14596.             @subscriber_conflictcount =  subscriber_conflictcount,
  14597.             -- Note: return average rate here !!! delivery_rate column is current rate
  14598.             @delivery_rate = 
  14599.                 case    when duration <> 0 then 
  14600.                             (publisher_insertcount + publisher_updatecount +
  14601.                             publisher_deletecount + subscriber_insertcount + 
  14602.                             subscriber_updatecount + subscriber_deletecount)/duration
  14603.                         when duration = 0 then 0
  14604.                 end, 
  14605.             @error_id = error_id, @last_timestamp = timestamp
  14606.             from MSmerge_history
  14607.             where
  14608.                 agent_id = @agent_id and
  14609.                 timestamp = (select max(timestamp) from MSmerge_history 
  14610.                     where agent_id = @agent_id)
  14611. /* Not currently working Build 351
  14612.                 timestamp = (select top 1 timestamp from MSmerge_history 
  14613.                     where agent_id = @agent_id
  14614.                     order by timestamp DESC) 
  14615. */
  14616.         
  14617.             insert into #merge_subscriptions values ( @subscriber, @status, @subscriber_db,
  14618.                 @type, @agent_name, @comments, @time, @start_time, @duration,
  14619.                 @delivery_rate, 
  14620.                 @publisher_insertcount, @publisher_updatecount, @publisher_deletecount, 
  14621.                 @publisher_conflictcount,
  14622.                 @subscriber_insertcount, @subscriber_updatecount, @subscriber_deletecount, 
  14623.                 @subscriber_conflictcount,
  14624.                 @error_id, @job_id, @local_job, @profile_id, @agent_id, @last_timestamp)
  14625.         
  14626.  
  14627.         fetch hC into  @subscriber_id, @subscriber_db, @agent_name, @job_id, @local_job, @profile_id, @agent_id, @subscriber_name
  14628.       end
  14629.  
  14630.     select * from #merge_subscriptions order by job_id asc
  14631.  
  14632.     drop table #merge_subscriptions
  14633.     close hC
  14634.     deallocate hC
  14635.  
  14636. go
  14637.  
  14638. raiserror(15339,-1,-1,'sp_update_agent_profile')
  14639. GO
  14640.  
  14641. -- Update the profile for an agent
  14642. CREATE PROCEDURE sp_update_agent_profile (
  14643.     @agent_type     int,
  14644.     @agent_id       int,
  14645.     @profile_id int
  14646. )
  14647. AS
  14648.     SET NOCOUNT ON
  14649.  
  14650.     DECLARE @proc               nvarchar(255)
  14651.  
  14652.     DECLARE @snapshot_type          int
  14653.     DECLARE @logreader_type         int
  14654.     DECLARE @distribution_type      int
  14655.     DECLARE @merge_type         int
  14656.  
  14657.     SELECT @snapshot_type = 1
  14658.     SELECT @logreader_type = 2
  14659.     SELECT @distribution_type = 3
  14660.     SELECT @merge_type = 4
  14661.  
  14662.     IF @agent_type NOT IN (@snapshot_type, @logreader_type, @distribution_type, @merge_type)
  14663.         RETURN (1) 
  14664.  
  14665.     /* The profile must be defined for the agent type in MSagent_profiles table */
  14666.     IF NOT EXISTS ( select * from msdb..MSagent_profiles
  14667.             where profile_id = @profile_id
  14668.             and agent_type = @agent_type )
  14669.         RETURN (1)
  14670.  
  14671.     SELECT @proc = 'UPDATE ' +
  14672.         CASE @agent_type
  14673.            WHEN @snapshot_type THEN 'MSsnapshot_agents'
  14674.            WHEN @logreader_type THEN 'MSlogreader_agents'
  14675.            WHEN @distribution_type THEN 'MSdistribution_agents'
  14676.            WHEN @merge_type THEN 'MSmerge_agents'
  14677.         END
  14678.         + ' SET profile_id = ' + convert(nvarchar(10), @profile_id)
  14679.         + ' WHERE id = ' + convert(nvarchar(10), @agent_id)
  14680.  
  14681.     EXECUTE (@proc)
  14682.  
  14683.     IF @@ERROR <> 0 
  14684.         RETURN (1)
  14685. GO
  14686.  
  14687.  
  14688. raiserror(15339,-1,-1,'sp_MSprofile_in_use')
  14689. GO
  14690.  
  14691. CREATE PROCEDURE sp_MSprofile_in_use (
  14692.     @tablename          nvarchar(255),
  14693.     @profile_id int
  14694. )
  14695. AS
  14696.     DECLARE @usage_count int
  14697.  
  14698.     IF @tablename IS NULL OR @profile_id IS NULL
  14699.         return 1 ;
  14700.  
  14701.     IF @tablename = 'MSsnapshot_agents'
  14702.         SELECT @usage_count = count(*) FROM MSsnapshot_agents
  14703.         WHERE profile_id = @profile_id
  14704.     ELSE IF @tablename = 'MSlogreader_agents'
  14705.             SELECT @usage_count = count(*) FROM MSlogreader_agents
  14706.             WHERE profile_id = @profile_id
  14707.         ELSE IF @tablename = 'MSdistribution_agents'
  14708.                 SELECT @usage_count = count(*) FROM MSdistribution_agents
  14709.                 WHERE profile_id = @profile_id
  14710.             ELSE IF @tablename = 'MSmerge_agents'
  14711.                     SELECT @usage_count = count(*) FROM MSmerge_agents 
  14712.                     WHERE profile_id = @profile_id
  14713.                 ELSE 
  14714.                     SELECT @usage_count = 0
  14715.  
  14716.     IF @usage_count = 0
  14717.         RETURN -1
  14718.     ELSE
  14719.         RETURN 0
  14720. GO
  14721.  
  14722.  
  14723. raiserror(15339,-1,-1,'sp_MSreset_subscription')
  14724. GO
  14725. CREATE PROCEDURE sp_MSreset_subscription (
  14726.     @publisher sysname,
  14727.     @publisher_db sysname,
  14728.     @publication sysname,  
  14729.     @subscriber sysname,
  14730.     @subscriber_db sysname,
  14731.     @subscription_type int  -- have to have it to identify a distribution agent.
  14732. ) AS
  14733.  
  14734.  
  14735.     SET NOCOUNT ON
  14736.  
  14737.     /*
  14738.     ** Declarations.
  14739.     */
  14740.     DECLARE @retcode            int
  14741.     DECLARE @publisher_id       smallint
  14742.     DECLARE @subscriber_id      smallint
  14743.     DECLARE @virtual            smallint
  14744.     declare @publication_id        int
  14745.     declare @immediate_sync        bit
  14746.  
  14747.  
  14748.     /*
  14749.     ** Initializations
  14750.     */
  14751.     select @virtual = -1
  14752.  
  14753.     select @publisher_id = srvid from master..sysservers where 
  14754.         UPPER(srvname) = UPPER(@publisher)
  14755.  
  14756.     select @subscriber_id = srvid from master..sysservers where 
  14757.         UPPER(srvname) = UPPER(@subscriber) 
  14758.  
  14759.     select @publication_id = publication_id, @immediate_sync = immediate_sync
  14760.         from MSpublications where
  14761.         publisher_id = @publisher_id AND
  14762.         publisher_db = @publisher_db AND
  14763.         publication = @publication
  14764.  
  14765.     if @subscriber is NULL
  14766.         select @subscriber_id = @virtual
  14767.  
  14768.     -- No need to have 2 updates in one transaction.
  14769.     if @immediate_sync = 1
  14770.     begin
  14771.         UPDATE MSdistribution_agents SET subscription_guid = newid()
  14772.             WHERE
  14773.             publisher_id = @publisher_id AND
  14774.             publisher_db = @publisher_db AND
  14775.             publication = @publication and
  14776.             subscriber_id = @subscriber_id and
  14777.             subscriber_db = @subscriber_db and
  14778.             subscription_type = @subscription_type
  14779.  
  14780.         IF @@ERROR <> 0
  14781.             GOTO UNDO
  14782.     end
  14783.  
  14784.     UPDATE MSsubscriptions set subscription_time = getdate() 
  14785.         WHERE
  14786.         publisher_id = @publisher_id AND
  14787.         publisher_db = @publisher_db AND
  14788.         publication_id = @publication_id and
  14789.         subscriber_id = @subscriber_id and
  14790.         subscriber_db = @subscriber_db and
  14791.         subscription_type = @subscription_type
  14792.  
  14793.     IF @@ERROR <> 0
  14794.         GOTO UNDO
  14795.  
  14796.     RETURN(0)
  14797.  
  14798. UNDO:
  14799.     return(1)
  14800. GO
  14801.  
  14802. raiserror(15339,-1,-1,'sp_MSget_subscription_guid')
  14803. GO
  14804. CREATE PROCEDURE sp_MSget_subscription_guid
  14805. @agent_id int
  14806.  
  14807. as
  14808.    set nocount on
  14809.     
  14810.    select a1.subscription_guid from MSdistribution_agents a1
  14811.     where
  14812.     -- for non anonymous agents
  14813.     (a1.virtual_agent_id is null and a1.id = @agent_id) or
  14814.     (   -- for anonymous agents
  14815.         a1.id = (select virtual_agent_id from MSdistribution_agents a2 where
  14816.             a2.id = @agent_id)) -- virtual account
  14817.             
  14818. GO
  14819.  
  14820.  
  14821. raiserror(15339,-1,-1,'sp_MShelp_profile')
  14822. GO
  14823.  
  14824. CREATE PROCEDURE sp_MShelp_profile (        
  14825.     @agent_id   int,
  14826.     @agent_type int,
  14827.     @profile_name sysname = NULL
  14828. )
  14829. as
  14830.     declare @profile_id int
  14831.     declare @snapshot_type int
  14832.     declare @logreader_type int
  14833.     declare @distribution_type int
  14834.     declare @merge_type int
  14835.  
  14836.     select @snapshot_type = 1
  14837.     select @logreader_type = 2
  14838.     select @distribution_type = 3
  14839.     select @merge_type = 4
  14840.  
  14841.     select @profile_id = NULL
  14842.  
  14843.     if (@profile_name is not null) and (rtrim(ltrim(@profile_name)) <> '')
  14844.     begin
  14845.         select @profile_id = profile_id from msdb..MSagent_profiles where
  14846.             agent_type = @agent_type and profile_name = @profile_name
  14847.  
  14848.         /* raise error if profile not found */
  14849.         if (@profile_id is null)
  14850.         begin
  14851.             raiserror(21123, 16, -1, @profile_name)
  14852.             return (1)
  14853.         end
  14854.     end
  14855.     
  14856.     -- if profile name not specified, use default.
  14857.     if (@profile_id is null)
  14858.     begin
  14859.         if @agent_type = @snapshot_type 
  14860.         begin
  14861.             if @agent_id = 0
  14862.                 select @profile_id = profile_id from msdb..MSagent_profiles where
  14863.                     agent_type = @agent_type and def_profile = 1
  14864.             else
  14865.                 select @profile_id = profile_id from MSsnapshot_agents
  14866.                     where id = @agent_id
  14867.         end
  14868.         else if @agent_type = @logreader_type
  14869.         begin
  14870.             if @agent_id = 0
  14871.                 select @profile_id = profile_id from msdb..MSagent_profiles where
  14872.                     agent_type = @agent_type and def_profile = 1
  14873.             else
  14874.                 select @profile_id = profile_id from MSlogreader_agents
  14875.                     where id = @agent_id
  14876.         end
  14877.         else if @agent_type = @distribution_type
  14878.         begin
  14879.             if @agent_id = 0
  14880.                 select @profile_id = profile_id from msdb..MSagent_profiles where
  14881.                     agent_type = @agent_type and def_profile = 1
  14882.             else
  14883.                 select @profile_id = profile_id from MSdistribution_agents
  14884.                     where id = @agent_id
  14885.         end
  14886.         else if @agent_type = @merge_type
  14887.         begin
  14888.             if @agent_id = 0
  14889.                 select @profile_id = profile_id from msdb..MSagent_profiles where
  14890.                     agent_type = @agent_type and def_profile = 1
  14891.             else
  14892.                 select @profile_id = profile_id from MSmerge_agents
  14893.                     where id = @agent_id
  14894.         end
  14895.     end
  14896.     
  14897.     select profile_id, parameter_name, value 
  14898.         from msdb..MSagent_parameters
  14899.         where profile_id = @profile_id
  14900. GO
  14901.  
  14902. raiserror(15339,-1,-1,'sp_MShelp_snapshot_agentid')
  14903. GO
  14904.  
  14905. CREATE PROCEDURE sp_MShelp_snapshot_agentid (
  14906.     @publisher_id       smallint,
  14907.     @publisher_db       sysname,
  14908.     @publication        sysname,
  14909.     @job_id             binary(16) = NULL
  14910. )
  14911. AS
  14912.     set nocount on
  14913.     declare @retcode int
  14914.     declare @publisher sysname
  14915.     declare @description nvarchar(255)
  14916.  
  14917.     -- Check if agent exists, if not and there is an 6.x tasks then create one
  14918.     if @publication is not null and @publication <> '' and not exists (select * from MSsnapshot_agents where
  14919.             publisher_id = @publisher_id and
  14920.             publisher_db = @publisher_db and
  14921.             publication = @publication)
  14922.     begin
  14923.         -- Do it only if the agent name is valid. It will be the case if
  14924.         -- the agent is launched by SQL Server Agent
  14925.         if exists (select * from msdb..sysjobs_view where
  14926.             job_id = @job_id)
  14927.         begin
  14928.             select @publisher = srvname from master..sysservers where srvid = @publisher_id
  14929.             begin tran
  14930.             exec @retcode = dbo.sp_MSadd_snapshot_agent
  14931.                 @publisher = @publisher, 
  14932.                 @publisher_db = @publisher_db,
  14933.                 @publication = @publication,
  14934.                 @local_job = 1,
  14935.                 @job_existing = 1,
  14936.                 @snapshot_jobid = @job_id
  14937.             if @@ERROR<> 0 or @retcode <> 0
  14938.                 goto UNDO
  14939.  
  14940.             -- Add a publication definition so it shows up in monitoring procs
  14941.             set @description = formatmessage(20555)
  14942.             exec @retcode = dbo.sp_MSadd_publication
  14943.                 @publisher = @publisher,
  14944.                 @publisher_db = @publisher_db,
  14945.                 @publication = @publication,
  14946.                 @publication_type = 1,              -- Make all 6.x pubs transactional
  14947.                 @description = @description     -- 6.x publication description
  14948.  
  14949.             if @@ERROR<> 0 or @retcode <> 0
  14950.                 goto UNDO
  14951.             commit tran
  14952.         end
  14953.     end
  14954.  
  14955.     select id, name from MSsnapshot_agents  where 
  14956.         publisher_id = @publisher_id and
  14957.         publisher_db = @publisher_db and
  14958.         publication = @publication
  14959.  
  14960.     return(0)
  14961.  
  14962. UNDO:
  14963.     if @@TRANCOUNT = 1
  14964.         ROLLBACK TRAN
  14965.     else
  14966.         COMMIT TRAN
  14967.     return(1)
  14968. GO
  14969.  
  14970. raiserror(15339,-1,-1,'sp_MShelp_logreader_agentid')
  14971. GO
  14972.  
  14973. CREATE PROCEDURE sp_MShelp_logreader_agentid (
  14974.     @publisher_id       smallint,
  14975.     @publisher_db       sysname
  14976. )
  14977. AS
  14978.     set nocount on
  14979.     declare @retcode int
  14980.     declare @publisher sysname
  14981.     declare @job_id binary(16)
  14982.     declare @qv_package    varchar(20)
  14983.     declare @desk_top        int
  14984.     declare @license_value int
  14985.     declare @qv_value_package int
  14986.  
  14987.     select @qv_package = '845129433'
  14988.     select @license_value = 0 
  14989.     select @desk_top = 3
  14990.             
  14991.     exec @qv_value_package = master..xp_qv @qv_package
  14992.     if @@ERROR<>0 
  14993.         begin
  14994.             raiserror(20089, 16, -1)
  14995.             return (1)
  14996.         end
  14997.     if @qv_value_package = 1         --- 1 means desktop
  14998.         select @license_value = @desk_top   -- to be consistent with all other compenents.
  14999.     
  15000.     -- Check if agent exists, if not and there is an 6.x tasks then create one
  15001.     if not exists (select * from MSlogreader_agents where
  15002.             publisher_id = @publisher_id and
  15003.             publisher_db = @publisher_db)
  15004.     begin
  15005.         select @publisher = srvname from master..sysservers where srvid = @publisher_id
  15006.  
  15007.         -- Do it only if the agent name is valid. It will be the case if
  15008.         -- the agent is launched by SQL Server Agent
  15009.         select @job_id = id.job_id from msdb..systasks_view v,
  15010.             msdb..systaskids id
  15011.             where 
  15012.             v.server = @publisher and           
  15013.             v.databasename = @publisher_db and
  15014.             v.subsystem = 'LogReader' and
  15015.             v.id = id.task_id
  15016.  
  15017.         if @job_id is not NULL
  15018.         begin
  15019.             exec @retcode = dbo.sp_MSadd_logreader_agent
  15020.                 @publisher = @publisher, 
  15021.                 @publisher_db = @publisher_db,
  15022.                 -- 'ALL' is Used in sp_addpublication as well
  15023.                 @publication = 'ALL',
  15024.                 @local_job = 1,
  15025.                 @job_existing = 1,
  15026.                 @job_id = @job_id
  15027.             if @@ERROR<> 0 or @retcode <> 0
  15028.                 return(1)
  15029.         end
  15030.     end
  15031.   
  15032.     select id, name, @license_value from MSlogreader_agents where 
  15033.         publisher_id = @publisher_id and 
  15034.         publisher_db = @publisher_db
  15035.  
  15036.     return(0)
  15037.  
  15038. GO
  15039.  
  15040. /*
  15041. ** This procedure is to add an agent row in MSmerge_agents for an anonymous subscription,
  15042. ** if it is not already there. If it is, return the agentid and agent name for monitoring
  15043. ** purpose.
  15044. */
  15045. raiserror(15339,-1,-1,'sp_MSadd_merge_anonymous_agent')
  15046. GO
  15047.  
  15048. CREATE PROCEDURE sp_MSadd_merge_anonymous_agent (
  15049.     @publisher_id       smallint,
  15050.     @publisher_db       sysname,
  15051.     @publication        sysname,
  15052.     @subscriber_db      sysname,
  15053.     @subscriber_name    sysname,
  15054.     @subid              uniqueidentifier, 
  15055.     @first_anonymous    int        -- 0 means this is the first time for this anonymous agent being ran.
  15056. )
  15057. AS
  15058.     declare @min_valid_day  datetime
  15059.     declare @merge_type     int
  15060.     declare @profile_id     int
  15061.     declare @subscriber_id  smallint
  15062.     declare @agent_name     sysname
  15063.     declare @agent_id       int
  15064.     declare @retcode        int
  15065.     declare @publication_id int
  15066.     declare @not_exist      bit
  15067.     declare @last_status    int
  15068.     declare @last_history    datetime
  15069.     declare @merge_jobid    uniqueidentifier
  15070.     declare @by_pass        bit
  15071.     declare @retention        int
  15072.     declare @success        int
  15073.     declare @expired        int
  15074.     declare @dropped        int
  15075.     declare @allow_anonymous bit
  15076.  
  15077.     select @dropped = 0
  15078.     select @expired = 0
  15079.     select @success = 2
  15080.     select @by_pass = 0
  15081.  
  15082. /*
  15083. ** This stored procedure does not really add a job at distribution database;
  15084. ** if add a row in MSmerge_agent table for anonymous subscription for the 
  15085. ** purpose of history logging
  15086. */
  15087.  
  15088.     -- Check to see if the publication is valid and allow anonymous
  15089.     select @publication_id = publication_id, @allow_anonymous = allow_anonymous, @retention = retention from MSpublications where
  15090.         publisher_id = @publisher_id and
  15091.         publisher_db = @publisher_db and
  15092.         publication = @publication
  15093.  
  15094.     if @publication_id is null
  15095.     begin
  15096.         RAISERROR (21040, 16, -1, @publication)
  15097.         return 1
  15098.     end
  15099.  
  15100.     if @allow_anonymous = 0
  15101.     begin
  15102.         RAISERROR (21084, 16, -1, @publication)
  15103.         return 1
  15104.     end
  15105.  
  15106.     if @subscriber_name is null
  15107.         select @subscriber_name = N''
  15108.  
  15109.     if @retention is NULL or @retention =0
  15110.         select @by_pass = 1
  15111.  
  15112.     -- Security check
  15113.     exec @retcode = dbo.sp_MScheck_pull_access
  15114.         @publication_id = @publication_id, @agent_type = 1
  15115.     if @retcode <> 0 or @@error <> 0
  15116.         return (1)
  15117.  
  15118.     select @not_exist = 0
  15119.     SELECT @merge_type = 4
  15120.     select @subscriber_id = 0  -- For anonymous subscribers, ID is always 0 
  15121.  
  15122.     SELECT @profile_id = profile_id
  15123.     FROM msdb..MSagent_profiles
  15124.     WHERE agent_type = @merge_type
  15125.         AND def_profile = 1
  15126.  
  15127.     IF @profile_id IS NULL
  15128.         RETURN (1)
  15129.  
  15130.     /*
  15131.     ** This is to handle Jet only
  15132.     */
  15133.     IF @subid = '00000000-0000-0000-0000-000000000000'
  15134.     begin
  15135.         select @subid = anonymous_subid from MSmerge_agents 
  15136.                 where publisher_id=@publisher_id and 
  15137.                       publisher_db = @publisher_db and 
  15138.                       publication = @publication and 
  15139.                       subscriber_id = @subscriber_id 
  15140.                       and subscriber_db = @subscriber_db
  15141.         if @subid = '00000000-0000-0000-0000-000000000000'
  15142.             select @subid = newid()
  15143.         else
  15144.             select @first_anonymous = 1   -- for Jet, schemaversion should not be 0 in this path.
  15145.     end
  15146.          
  15147.     IF NOT EXISTS (select * from MSmerge_agents where anonymous_subid=@subid)
  15148.     begin
  15149.  
  15150.         if @first_anonymous <= 0   --only add agent entry for initial subscription only. 
  15151.         begin
  15152.             select @not_exist = 1
  15153.  
  15154.             -- Generate a job GUID for remote agents. This will be used by the UI to uniquely
  15155.             -- identify rows returned by the enums
  15156.             set @merge_jobid = newid();
  15157.  
  15158.             insert into MSmerge_agents (name, publisher_id, publisher_db, publication, 
  15159.                         subscriber_id, subscriber_db, anonymous_subid, job_id, profile_id, subscriber_name)
  15160.                     VALUES (convert(nvarchar(40), @subid), @publisher_id, @publisher_db, @publication, 
  15161.                             @subscriber_id, @subscriber_db, @subid, @merge_jobid, @profile_id, @subscriber_name)
  15162.         end
  15163.         else
  15164.             select @dropped  =1
  15165.     end
  15166.     
  15167.     select @agent_id = id, @agent_name = name from MSmerge_agents 
  15168.         where anonymous_subid=@subid  -- subid guarantees uniqueness
  15169.     
  15170.     if @by_pass = 0 --by pass the checking if retention is NULL or 0
  15171.     begin
  15172.         select @min_valid_day = dateadd(day, -@retention, getdate())
  15173.         
  15174.         select Top 1 @last_status = runstatus, @last_history = time from MSmerge_history where agent_id = @agent_id
  15175.                     order by time DESC
  15176.         if @last_status = 6 and EXISTS (select * from MSmerge_history where agent_id = @agent_id and runstatus = 2) 
  15177.                 select Top 1 @last_history = time from MSmerge_history where agent_id = @agent_id and runstatus = 2
  15178.                         order by time DESC    
  15179.         /*
  15180.         ** This anonymous subscription is gone for too long to be efficiently reconciled. Either reinitialization or
  15181.         ** re-deployment of this subscription is needed. Merge agent will fail.
  15182.         */
  15183.         if @last_history < @min_valid_day and @first_anonymous <> 0    --do not check for re-initialized replicas.
  15184.                     select @expired = 1
  15185.    end
  15186.  
  15187.     select @agent_id, @agent_name, @expired where @dropped = 0 --return empty result set 
  15188.         
  15189. GO
  15190.  
  15191.  
  15192. raiserror(15339,-1,-1,'sp_MShelp_merge_agentid')
  15193. GO
  15194.  
  15195. CREATE PROCEDURE sp_MShelp_merge_agentid (
  15196.     @publisher_id       smallint,
  15197.     @publisher_db       sysname,
  15198.     @publication        sysname,
  15199.     @subscriber_id      smallint,
  15200.     @subscriber_db      sysname
  15201. )
  15202. AS
  15203.     declare @publisher        sysname
  15204.     declare @subscriber        sysname
  15205.     declare @expired        int
  15206.     declare @agent_id         int
  15207.     declare @name             sysname
  15208.     declare @retention         int
  15209.     declare @last_status    int
  15210.     declare @last_history    datetime
  15211.     declare @min_valid_day     datetime
  15212.     declare @reinited         int
  15213.     declare @status         int
  15214.     declare @success        int
  15215.     declare @publication_id    int
  15216.     declare @subscriber_datasource_type int
  15217.     declare @sql_subscriber    int
  15218.  
  15219.     select @expired = 0
  15220.     select @reinited = 4
  15221.     select @success = 2
  15222.  
  15223.     select @subscriber_datasource_type = 0
  15224.     select @sql_subscriber = 0
  15225.  
  15226.     if not EXISTS (select * from MSpublications 
  15227.         where publisher_id=@publisher_id 
  15228.         and publisher_db = @publisher_db
  15229.         and publication = @publication
  15230.         and publication_type = 2) -- merge publication is gone
  15231.     begin
  15232.         select 1, @publication, 1, 0 --third column = 1 means publication is gone, making the other values meanningless.
  15233.         return (1)
  15234.     end
  15235.  
  15236.        select @publication_id = publication_id 
  15237.         from MSpublications
  15238.         where publisher_id = @publisher_id and
  15239.               publisher_db = @publisher_db and
  15240.               publication = @publication
  15241.  
  15242.     -- Get subscriber info
  15243.     select @subscriber = srvname from master..sysservers where srvid = @subscriber_id
  15244.     select @publisher = srvname from master..sysservers where srvid = @publisher_id
  15245.  
  15246.     select @subscriber_datasource_type = type
  15247.         from MSsubscriber_info 
  15248.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  15249.  
  15250.     if (@subscriber_datasource_type = @sql_subscriber)
  15251.     begin
  15252.         select @status = status from MSmerge_subscriptions where
  15253.             publisher_id = @publisher_id and 
  15254.             publisher_db = @publisher_db and 
  15255.             publication_id = @publication_id and
  15256.             subscriber_id = @subscriber_id and
  15257.             subscriber_db = @subscriber_db
  15258.  
  15259.         select @agent_id = id, @name = name from MSmerge_agents 
  15260.             where publisher_id = @publisher_id 
  15261.             and publisher_db = @publisher_db
  15262.             and publication = @publication
  15263.             and subscriber_id = @subscriber_id
  15264.             and subscriber_db = @subscriber_db
  15265.     end
  15266.     else
  15267.     begin
  15268.         select @status = status from MSmerge_subscriptions where
  15269.             publisher_id = @publisher_id and 
  15270.             publisher_db = @publisher_db and 
  15271.             publication_id = @publication_id and
  15272.             subscriber_id = @subscriber_id
  15273.  
  15274.         select @agent_id = id, @name = name from MSmerge_agents 
  15275.             where publisher_id = @publisher_id 
  15276.             and publisher_db = @publisher_db
  15277.             and publication = @publication
  15278.             and subscriber_id = @subscriber_id
  15279.     end
  15280.  
  15281.     -- Security check. Do it here to let the agent fail at the beginning
  15282.     if @agent_id is not null
  15283.     begin
  15284.         exec dbo.sp_MScheck_pull_access @agent_id = @agent_id, @agent_type = 1 -- distribution agent
  15285.         select @retention = retention 
  15286.             from MSpublications 
  15287.             where publisher_id=@publisher_id and publisher_db=@publisher_db and publication=@publication 
  15288.  
  15289.         if @retention is not NULL and @retention > 0
  15290.         begin
  15291.             select @min_valid_day = dateadd(day, @retention * (-1), getdate()) 
  15292.             select Top 1 @last_status = runstatus, @last_history = time 
  15293.                     from MSmerge_history where agent_id = @agent_id
  15294.                         order by time DESC
  15295.             if @last_status = 6 and EXISTS (select * from MSmerge_history where  agent_id = @agent_id and runstatus = 2) 
  15296.                 select Top 1 @last_history = time from MSmerge_history where agent_id = @agent_id and runstatus = 2
  15297.                                 order by time DESC    
  15298.             if @last_history < @min_valid_day and @status <> @reinited
  15299.                 select @expired = 1
  15300.         end
  15301.     end
  15302.  
  15303. select @agent_id, @name, 0, @expired where @agent_id is not NULL
  15304. GO
  15305.  
  15306. raiserror(15339,-1,-1,'sp_MSdistpublisher_cleanup')
  15307. GO
  15308.  
  15309. CREATE PROCEDURE sp_MSdistpublisher_cleanup 
  15310. @publisher sysname
  15311. as
  15312.  
  15313.     set nocount on
  15314.     declare @publisher_id smallint
  15315.     declare @job_id binary(16)
  15316.     declare @retcode int
  15317.     
  15318.     -- Delete agents
  15319.     -- Get the publisher id
  15320.     -- Check if publisher is a defined as a distribution publisher in the current database
  15321.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  15322.     if @retcode <> 0
  15323.     begin
  15324.         return(1)
  15325.     end
  15326.     
  15327.     -- Dropping local jobs
  15328.     -- Use union in 'select'. Insensitive cursor will be used automatically.
  15329.     DECLARE hCagents CURSOR LOCAL FAST_FORWARD FOR
  15330.             SELECT job_id 
  15331.                 FROM MSsnapshot_agents
  15332.                 WHERE publisher_id = @publisher_id and local_job = 1
  15333.         UNION
  15334.             SELECT job_id
  15335.                 FROM MSlogreader_agents
  15336.                 WHERE publisher_id = @publisher_id and local_job = 1
  15337.         UNION
  15338.             SELECT job_id 
  15339.                 FROM MSdistribution_agents
  15340.                 WHERE publisher_id = @publisher_id and local_job = 1
  15341.         UNION
  15342.             SELECT job_id
  15343.                 FROM MSmerge_agents
  15344.                 WHERE publisher_id = @publisher_id  and local_job = 1
  15345.         FOR READ ONLY
  15346.  
  15347.     OPEN hCagents
  15348.     FETCH hCagents INTO @job_id
  15349.    
  15350.     WHILE (@@fetch_status <> -1)
  15351.     BEGIN
  15352.         IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE job_id = @job_id)
  15353.         BEGIN
  15354.             exec @retcode = msdb.dbo.sp_delete_job @job_id = @job_id
  15355.             if @retcode <> 0 or @@error <> 0
  15356.                 return(1)
  15357.         END
  15358.         FETCH hCagents INTO @job_id 
  15359.     end
  15360.  
  15361.     -- Clean up the tables, including
  15362.     --  4 Agent tables
  15363.     --  2 subscription tables
  15364.     --  article table
  15365.     --  publication table
  15366.     --  2 subscriber table
  15367.     -- The order is to avoid breaking monitoring
  15368.  
  15369.  
  15370.     delete MSpublisher_databases where publisher_id = @publisher_id
  15371.     if @@error <> 0 
  15372.         return (1) 
  15373.  
  15374.     delete MSpublications where publisher_id = @publisher_id
  15375.     if @@error <> 0 
  15376.         return (1) 
  15377.  
  15378.     delete MSarticles where publisher_id = @publisher_id
  15379.     if @@error <> 0 
  15380.         return (1) 
  15381.  
  15382.     delete MSsubscriptions where publisher_id = @publisher_id
  15383.     if @@error <> 0 
  15384.         return (1) 
  15385.  
  15386.     delete MSmerge_subscriptions where publisher_id = @publisher_id
  15387.     if @@error <> 0 
  15388.         return (1) 
  15389.  
  15390.     delete MSsnapshot_agents where publisher_id = @publisher_id
  15391.     if @@error <> 0 
  15392.         return (1) 
  15393.     
  15394.     delete MSlogreader_agents where publisher_id = @publisher_id
  15395.     if @@error <> 0 
  15396.         return (1) 
  15397.  
  15398.     delete MSdistribution_agents where publisher_id = @publisher_id
  15399.     if @@error <> 0 
  15400.         return (1) 
  15401.  
  15402.     delete MSmerge_agents where publisher_id = @publisher_id
  15403.     if @@error <> 0 
  15404.         return (1) 
  15405.  
  15406.     delete MSsubscriber_info where UPPER(publisher) = UPPER(@publisher)
  15407.     if @@error <> 0 
  15408.         return (1) 
  15409.  
  15410.     delete MSsubscriber_schedule where UPPER(publisher) = UPPER(@publisher)
  15411.     if @@error <> 0 
  15412.         return (1) 
  15413.  
  15414.     delete MSpublication_access where not exists (select * from MSpublications p where
  15415.         p.publication_id = MSpublication_access.publication_id)
  15416.     if @@error <> 0 
  15417.         return (1) 
  15418.  
  15419.     delete MSrepl_originators where 
  15420.         not exists (select * from MSpublisher_databases p
  15421.             where p.id = MSrepl_originators.publisher_database_id )
  15422.     if @@error <> 0 
  15423.         return (1) 
  15424.  
  15425.     -- Force a refresh of the replication status temp table.
  15426.     if (select object_id('tempdb.dbo.MSreplication_agent_status')) is not NULL
  15427.         drop table tempdb.dbo.MSreplication_agent_status
  15428. GO
  15429.  
  15430. raiserror(15339,-1,-1,'sp_MSenum_replication_status')
  15431. GO
  15432.  
  15433. create proc sp_MSenum_replication_status
  15434. as
  15435.  
  15436.     select 'publisher' = srvname, 'publisher_db' = sa.publisher_db, 
  15437.         'publication' = sa.publication, 'publication_type' = sa.publication_type,
  15438.         'agent_type' = 1, 'status' = runstatus, 'agent_name' = sa.name from 
  15439.         MSsnapshot_history sh1, master..sysservers, MSsnapshot_agents sa
  15440.         where 
  15441.         sh1.timestamp = (select max(timestamp) from MSsnapshot_history sh2 where
  15442.             sh2.agent_id = sa.id) and
  15443.         srvid = sa.publisher_id 
  15444.     UNION
  15445.     select srvname, sa.publisher_db, sa.publication, sa.publication_type, 
  15446.         1, 0, sa.name from 
  15447.         master..sysservers, MSsnapshot_agents sa
  15448.         where 
  15449.         srvid = sa.publisher_id and
  15450.         not exists (select * from MSsnapshot_history sh where sh.agent_id = sa.id)
  15451.     UNION
  15452.     select srvname, la.publisher_db, 'ALL', 0, 2, runstatus, la.name from
  15453.         MSlogreader_history lh1, MSlogreader_agents la, master..sysservers
  15454.         where timestamp = (select max(timestamp) from 
  15455.             MSlogreader_history lh2 where
  15456.             lh2.agent_id = la.id) and
  15457.             srvid = la.publisher_id
  15458.     UNION
  15459.     select srvname, la.publisher_db, 'ALL', 0, 2, 0, la.name from
  15460.         MSlogreader_agents la, master..sysservers
  15461.         where
  15462.             srvid = la.publisher_id and
  15463.             not exists (select * from MSlogreader_history lh where lh.agent_id = la.id)
  15464.     UNION
  15465.     select srvname, da.publisher_db, da.publication, p.publication_type, 3, runstatus, da.name from 
  15466.             MSdistribution_history dh1, master..sysservers, 
  15467.             MSdistribution_agents da, MSpublications p, MSsubscriptions s
  15468.             where timestamp = (select max(timestamp) from 
  15469.                 MSdistribution_history dh2 where
  15470.                 dh2.agent_id = da.id) and
  15471.                 srvid = da.publisher_id and
  15472.                 s.agent_id = da.id and
  15473.                 p.publication_id = s.publication_id
  15474.     UNION
  15475.     select srvname, da.publisher_db, da.publication, p.publication_type, 3, 0, da.name from 
  15476.             master..sysservers, 
  15477.             MSdistribution_agents da,
  15478.             MSpublications p,
  15479.             MSsubscriptions s
  15480.             where 
  15481.                 srvid = da.publisher_id and
  15482.                 not exists (select * from MSdistribution_history dh where dh.agent_id = da.id) and
  15483.                 s.agent_id = da.id and
  15484.                 p.publication_id = s.publication_id
  15485.     UNION    -- Load distribution dummy rows
  15486.     select srvname, da.publisher_db, p.publication, p.publication_type, 3, runstatus, da.name from 
  15487.             MSdistribution_history dh1, master..sysservers, 
  15488.             MSdistribution_agents da, MSpublications p, MSsubscriptions s
  15489.             where timestamp = (select max(timestamp) from 
  15490.                 MSdistribution_history dh2 where
  15491.                 dh2.agent_id = da.id) and
  15492.                 srvid = da.publisher_id and
  15493.                 s.agent_id = da.id and
  15494.                 p.publication_id = s.publication_id
  15495.     UNION -- Load distrbution dummy_rows
  15496.     select srvname, da.publisher_db, p.publication, p.publication_type, 3, 0, da.name from 
  15497.             master..sysservers, 
  15498.             MSdistribution_agents da,
  15499.             MSpublications p,
  15500.             MSsubscriptions s
  15501.             where 
  15502.                 srvid = da.publisher_id and
  15503.                 not exists (select * from MSdistribution_history dh where dh.agent_id = da.id) and
  15504.                 s.agent_id = da.id and
  15505.                 p.publication_id = s.publication_id
  15506.     UNION
  15507.     select srvname, ma.publisher_db, ma.publication, 2, 4, runstatus, ma.name from 
  15508.         MSmerge_history mh1, master..sysservers, MSmerge_agents ma
  15509.         where timestamp = (select max(timestamp) from
  15510.             MSmerge_history mh2 where
  15511.             mh2.agent_id = ma.id) and
  15512.             srvid = ma.publisher_id 
  15513.  
  15514.     UNION
  15515.     select srvname, ma.publisher_db, ma.publication, 2, 4, 0, ma.name from 
  15516.         master..sysservers, MSmerge_agents ma
  15517.         where 
  15518.             srvid = ma.publisher_id and
  15519.             not exists (select * from MSmerge_history mh where mh.agent_id = ma.id)
  15520.  
  15521.  
  15522.     order by publisher, publisher_db, publication
  15523.  
  15524. go
  15525.  
  15526. raiserror(15339,-1,-1,'sp_MSagent_stethoscope')
  15527. GO
  15528. CREATE PROCEDURE sp_MSagent_stethoscope
  15529. @heartbeat_interval int = 10  --minutes
  15530. as
  15531.     declare @current_time datetime
  15532.     declare @agent_name nvarchar(100)
  15533.     declare @agent_id int
  15534.     declare @job_id binary(16)
  15535.     declare @start_time datetime
  15536.     declare @duration int
  15537.     declare @comments nvarchar(255)
  15538.     declare @publisher_id smallint
  15539.     declare @publisher sysname
  15540.     declare @publisher_db sysname
  15541.     declare @heartbeat_failure bit
  15542.  
  15543.     set nocount on
  15544.  
  15545.     set @heartbeat_failure = 0
  15546.     set @current_time = getdate()
  15547.  
  15548.     -- Construct suspect message
  15549.     set @comments = formatmessage(20554, @heartbeat_interval)
  15550.  
  15551.     -- If a running snapshot agent has not logged a history message within the specified
  15552.     -- heartbeat_interval then raise a agent suspect error
  15553.     declare hC_snapshot_suspect CURSOR LOCAL FAST_FORWARD for 
  15554.         select sh1.agent_id, sh1.start_time from MSsnapshot_history sh1 where
  15555.             (sh1.runstatus = 1 or sh1.runstatus = 3 or sh1.runstatus = 4) and
  15556.             dateadd(minute, @heartbeat_interval, sh1.time) < @current_time and
  15557.             sh1.timestamp = (select max(timestamp) from MSsnapshot_history where
  15558.                 agent_id= sh1.agent_id)
  15559.         for read only
  15560.  
  15561.     open hC_snapshot_suspect
  15562.     fetch hC_snapshot_suspect into @agent_id, @start_time
  15563.     while (@@fetch_status <> -1)
  15564.     begin
  15565.  
  15566.         set @heartbeat_failure = 1
  15567.  
  15568.         -- Get the agent name
  15569.         select @agent_name = name, @job_id = job_id from MSsnapshot_agents where id = @agent_id
  15570.  
  15571.         -- Log a "No action" message on behalf of the agent
  15572.         exec dbo.sp_MSadd_snapshot_history
  15573.             @agent_id = @agent_id,
  15574.             @runstatus = 6,     -- Failure status
  15575.             @comments = @comments,
  15576.             @do_raiserror = 0
  15577.  
  15578.         fetch hC_snapshot_suspect into @agent_id, @start_time
  15579.     end
  15580.     close hC_snapshot_suspect
  15581.     deallocate hC_snapshot_suspect
  15582.  
  15583.  
  15584.     -- If a running logreader agent has not logged a history message within the specified
  15585.     -- heartbeat_interval then raise a agent suspect error
  15586.     declare hC_logreader_suspect CURSOR LOCAL FAST_FORWARD for 
  15587.         select la.id, sh1.start_time from MSlogreader_agents la, MSlogreader_history sh1 where
  15588.             (sh1.runstatus = 1 or sh1.runstatus = 3 or sh1.runstatus = 4) and
  15589.             dateadd(minute, @heartbeat_interval, sh1.time) < @current_time and
  15590.             sh1.timestamp = (select max(timestamp) from MSlogreader_history where
  15591.                 agent_id= sh1.agent_id) and
  15592.             la.id = sh1.agent_id
  15593.         for read only
  15594.  
  15595.     open hC_logreader_suspect
  15596.     fetch hC_logreader_suspect into @agent_id, @start_time
  15597.     while (@@fetch_status <> -1)
  15598.     begin
  15599.         set @heartbeat_failure = 1
  15600.  
  15601.         -- Get the agent name
  15602.         select @agent_name = name, @job_id = job_id from MSlogreader_agents where id = @agent_id
  15603.  
  15604.         -- Log a "No action" message on behalf of the agent
  15605.         select @publisher_id = publisher_id, @publisher_db = publisher_db from MSlogreader_agents where id = @agent_id
  15606.         select @publisher = srvname from master..sysservers where srvid = @publisher_id
  15607.         exec dbo.sp_MSadd_logreader_history
  15608.             @agent_id = @agent_id,
  15609.             @runstatus = 6,     -- Failure status
  15610.             @comments = @comments,
  15611.             @do_raiserror = 0
  15612.  
  15613.         fetch hC_logreader_suspect into @agent_id, @start_time
  15614.     end
  15615.     close hC_logreader_suspect
  15616.     deallocate hC_logreader_suspect
  15617.  
  15618.     -- If a running distribution agent has not logged a history message within the specified
  15619.     -- heartbeat_interval then raise a agent suspect error
  15620.     declare hC_distribution_suspect CURSOR LOCAL FAST_FORWARD for 
  15621.         select sh1.agent_id, sh1.start_time from MSdistribution_history sh1 where
  15622.             (sh1.runstatus = 1 or sh1.runstatus = 3 or sh1.runstatus = 4) and
  15623.             dateadd(minute, @heartbeat_interval, sh1.time) < @current_time and
  15624.             sh1.timestamp = (select max(timestamp) from MSdistribution_history where
  15625.                 agent_id= sh1.agent_id)
  15626.         for read only
  15627.  
  15628.     open hC_distribution_suspect
  15629.     fetch hC_distribution_suspect into @agent_id, @start_time
  15630.     while (@@fetch_status <> -1)
  15631.     begin
  15632.         set @heartbeat_failure = 1
  15633.  
  15634.         -- Get the agent name
  15635.         select @agent_name = name, @job_id = job_id from MSdistribution_agents where id = @agent_id
  15636.  
  15637.         -- Log a "No action" message on behalf of the agent
  15638.         exec dbo.sp_MSadd_distribution_history
  15639.             @agent_id = @agent_id,
  15640.             @runstatus = 6,     -- Failure status
  15641.             @comments = @comments,
  15642.             @do_raiserror = 0
  15643.  
  15644.         fetch hC_distribution_suspect into @agent_id, @start_time
  15645.     end
  15646.     close hC_distribution_suspect
  15647.     deallocate hC_distribution_suspect
  15648.  
  15649.     -- If a running merge agent has not logged a history message within the specified
  15650.     -- heartbeat_interval then raise a agent suspect error
  15651.     declare hC_merge_suspect CURSOR LOCAL FAST_FORWARD for 
  15652.         select sh1.agent_id, sh1.start_time from MSmerge_history sh1 where
  15653.             (sh1.runstatus = 1 or sh1.runstatus = 3 or sh1.runstatus = 4) and
  15654.             dateadd(minute, @heartbeat_interval, sh1.time) < @current_time and
  15655.             sh1.timestamp = (select max(timestamp) from MSmerge_history where
  15656.                 agent_id= sh1.agent_id)
  15657.         for read only
  15658.  
  15659.     open hC_merge_suspect
  15660.     fetch hC_merge_suspect into @agent_id, @start_time
  15661.     while (@@fetch_status <> -1)
  15662.     begin
  15663.         set @heartbeat_failure = 1
  15664.  
  15665.         -- Get the agent name
  15666.         select @agent_name = name, @job_id = job_id from MSmerge_agents where id = @agent_id
  15667.  
  15668.         -- Log a "No action" message on behalf of the agent
  15669.         exec dbo.sp_MSadd_merge_history
  15670.             @agent_id = @agent_id,
  15671.             @runstatus = 6,     -- Failure status
  15672.             @comments = @comments,
  15673.             @do_raiserror = 0
  15674.  
  15675.         fetch hC_merge_suspect into @agent_id, @start_time
  15676.     end
  15677.     close hC_merge_suspect
  15678.     deallocate hC_merge_suspect
  15679.  
  15680.     -- Log all is fine message
  15681.     if @heartbeat_failure = 0
  15682.         -- "Detected heartbeat for all running Replication Agents"
  15683.         set @comments = formatmessage(20556)    
  15684.     else
  15685.         -- "Could not detected heartbeat for all running Replication Agents"
  15686.         set @comments = formatmessage(20580)    
  15687.  
  15688.     raiserror (20554, 10, -1, @heartbeat_interval)
  15689. GO
  15690. raiserror(15339,-1,-1,'sp_MSlock_distribution_agent')
  15691. GO
  15692.  
  15693. CREATE PROCEDURE sp_MSlock_distribution_agent (
  15694.     @id int,
  15695.     @mode int = 1 -- 0: shared  1: exclusive
  15696. ) AS
  15697.  
  15698.  
  15699.     SET         NOCOUNT ON
  15700.     DECLARE     @active tinyint
  15701.     declare     @count  int
  15702.     select @active = 2
  15703.     if @mode = 0
  15704.         select @count = count(*) from MSsubscriptions (ROWLOCK REPEATABLEREAD) where agent_id = @id and status = @active
  15705.     else
  15706.         select @count = count(*) from MSsubscriptions (ROWLOCK UPDLOCK) where agent_id = @id and status = @active
  15707. GO
  15708.  
  15709. raiserror(15339,-1,-1,'sp_MSdetect_nonlogged_shutdown')
  15710. GO
  15711. create proc sp_MSdetect_nonlogged_shutdown
  15712. @subsystem nvarchar(60),
  15713. @agent_id int
  15714. as
  15715.     declare @job_id binary(16)
  15716.     declare @agent_name nvarchar(100)
  15717.     declare @message nvarchar(1024)
  15718.     declare @retcode int
  15719.     declare @runstatus int
  15720.  
  15721.     -- Detect if the agent was shutdown without a logged reason
  15722.     if UPPER(@subsystem) = 'SNAPSHOT'
  15723.     begin
  15724.         if exists (select runstatus from MSsnapshot_history where 
  15725.             agent_id = @agent_id and
  15726.             runstatus <> 2 and 
  15727. --CAC       runstatus <> 5 and 
  15728.             runstatus <> 6 and
  15729.             timestamp = (select max(timestamp) from MSsnapshot_history where agent_id = @agent_id))
  15730.             begin
  15731.                 select @job_id = job_id, @agent_name = name from MSsnapshot_agents where id = @agent_id
  15732.             end
  15733.     end
  15734.     else if UPPER(@subsystem) = 'LOGREADER'
  15735.     begin
  15736.         if exists (select runstatus from MSlogreader_history where 
  15737.             agent_id = @agent_id and
  15738.             runstatus <> 2 and 
  15739. --CAC           runstatus <> 5 and 
  15740.             runstatus <> 6 and
  15741.             timestamp = (select max(timestamp) from MSlogreader_history where agent_id = @agent_id))
  15742.             begin
  15743.                 select @job_id = job_id, @agent_name = name from MSlogreader_agents where id = @agent_id
  15744.             end
  15745.     end
  15746.     else if UPPER(@subsystem) = 'DISTRIBUTION'
  15747.     begin
  15748.         if exists (select runstatus from MSdistribution_history where 
  15749.             agent_id = @agent_id and
  15750.             runstatus <> 2 and 
  15751. --CAC           runstatus <> 5 and 
  15752.             runstatus <> 6 and
  15753.             timestamp = (select max(timestamp) from MSdistribution_history where agent_id = @agent_id))
  15754.             begin
  15755.                 select @job_id = job_id, @agent_name = name from MSdistribution_agents where id = @agent_id
  15756.             end
  15757.     end
  15758.     else if UPPER(@subsystem) = 'MERGE'
  15759.     begin
  15760.         if exists (select runstatus from MSmerge_history where 
  15761.             agent_id = @agent_id and
  15762.             runstatus <> 2 and 
  15763. --CAC           runstatus <> 5 and 
  15764.             runstatus <> 6 and
  15765.             timestamp = (select max(timestamp) from MSmerge_history where agent_id = @agent_id))
  15766.             begin
  15767.                 select @job_id = job_id, @agent_name = name from MSmerge_agents where id = @agent_id
  15768.             end
  15769.     end
  15770.  
  15771.     -- If no job_id assume shutdown was logged properly
  15772.     if @job_id is null
  15773.         return 0
  15774.  
  15775.     -- Get last message from SQL Agent History table
  15776.     create table #JobHistory (
  15777.         instance_id int NOT NULL, 
  15778.         job_id uniqueidentifier NOT NULL,
  15779.         job_name nvarchar(100) NOT NULL,
  15780.         step_id int NOT NULL,
  15781.         step_name nvarchar(100) NOT NULL, 
  15782.         sql_message_id int NOT NULL,
  15783.         sql_severity int NOT NULL,
  15784.         message nvarchar(1024) NOT NULL,
  15785.         run_status int NOT NULL,
  15786.         run_date int NOT NULL,
  15787.         run_time int NOT NULL,
  15788.         run_duration int NOT NULL,
  15789.         operator_emailed sysname NULL,
  15790.         operator_netsent sysname NULL,
  15791.         operator_paged sysname NULL,
  15792.         retries_attempted int NOT NULL,
  15793.         server sysname NOT NULL
  15794.     )
  15795.     if @@error <> 0
  15796.         return 1
  15797.  
  15798.     -- Insert last history for step_id 2 (Agent running)
  15799.     set rowcount 1
  15800.     insert into #JobHistory exec msdb.dbo.sp_help_jobhistory @job_id = @job_id, @step_id = 2, 
  15801.         @mode = 'FULL'          
  15802.  
  15803.     -- Get the last history
  15804.     select @message = message, @runstatus = run_status from #JobHistory
  15805.  
  15806.     -- Reset rowcount
  15807.     set rowcount 0
  15808.  
  15809.     -- Map SQL Agent runstatus to Replication runstatus
  15810.     set @runstatus = 
  15811.     case @runstatus
  15812.         when 0 then 6   -- Fail mapping
  15813.         when 1 then 2   -- Success mapping
  15814.         when 2 then 5   -- Retry mapping
  15815.         when 3 then 2   -- Shutdown mapping
  15816.         when 4 then 3   -- Inprogress mapping
  15817.         when 5 then 0   -- Unknown is mapped to never run
  15818.     end
  15819.  
  15820.     -- If no message, provide a default message
  15821.     if @message is null
  15822.         select @message = formatmessage(20557, @agent_name)
  15823.  
  15824.     if UPPER(@subsystem) = 'SNAPSHOT'
  15825.         exec @retcode = dbo.sp_MSadd_snapshot_history @agent_id = @agent_id, @runstatus = @runstatus,
  15826.                 @comments = @message
  15827.     else if UPPER(@subsystem) = 'LOGREADER'
  15828.         exec @retcode = dbo.sp_MSadd_logreader_history @agent_id = @agent_id, @runstatus = @runstatus,
  15829.                 @comments = @message
  15830.     else if UPPER(@subsystem) = 'DISTRIBUTION'
  15831.         exec @retcode = dbo.sp_MSadd_distribution_history @agent_id = @agent_id, @runstatus = @runstatus,
  15832.                 @comments = @message
  15833.     else if UPPER(@subsystem) = 'MERGE'
  15834.         exec @retcode = dbo.sp_MSadd_merge_history @agent_id = @agent_id, @runstatus = @runstatus,
  15835.                 @comments = @message
  15836.  
  15837.     if @@error <> 0 or @retcode <> 0
  15838.         return 1
  15839.  
  15840.     drop table #JobHistory
  15841.  
  15842. GO
  15843.  
  15844. raiserror(15339,-1,-1,'sp_MSpublication_access')
  15845. GO
  15846.  
  15847. CREATE PROCEDURE sp_MSpublication_access (
  15848.     @publisher sysname,
  15849.     @publisher_db sysname = NULL,
  15850.     @publication sysname = NULL,
  15851.     @login sysname = NULL,
  15852.     @operation nvarchar(20), -- Can be add/drop/check/help/get_publications/get_logins
  15853.     @has_access bit = 0 output, -- Used only in check
  15854.     @skip bit = 0
  15855.         ) AS
  15856. -- This sp can be called repeatedly.
  15857.     
  15858.     declare @publisher_id smallint
  15859.     declare @retcode int
  15860.     declare @publication_id int
  15861.     declare @isntname bit
  15862.     declare @server_access bit
  15863.     declare @privilege nchar(21)
  15864.  
  15865.     -- Check if publisher is a defined as a distribution publisher in the current database
  15866.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  15867.     if @retcode <> 0
  15868.     begin
  15869.         return(1)
  15870.     end
  15871.  
  15872.     -- Check to see if the login exists and if the login is NT login
  15873.     select @isntname = isntname from master..syslogins where
  15874.         sid = suser_sid(@login) and
  15875.         hasaccess = 1
  15876.  
  15877.     -- Get the publication id 
  15878.     select @publication_id = publication_id from MSpublications where 
  15879.         publisher_id = @publisher_id and
  15880.         publisher_db = @publisher_db and
  15881.         publication = @publication
  15882.  
  15883.     -- Publication does not exist
  15884.     if @publication_id is null and
  15885.         @operation in ('add','drop','check','help')
  15886.     begin
  15887.         raiserror (20026, 16, -1, @publication)
  15888.         return (1)
  15889.     end
  15890.  
  15891.     if @operation = 'add'
  15892.     begin
  15893.         -- Login does not have access
  15894.         if @isntname is null
  15895.         begin
  15896.             if @skip = 0
  15897.             begin
  15898.                 raiserror(21048, 16, -1, @login, @@servername) 
  15899.                 return (1)
  15900.             end
  15901.             else
  15902.                 return (0)
  15903.         end
  15904.  
  15905.         -- Add login to the access list if it does not exist
  15906.         if not exists (select * from MSpublication_access where
  15907.             publication_id = @publication_id and
  15908.             login = @login)
  15909.         begin
  15910.             insert MSpublication_access (publication_id, login)
  15911.                 values (@publication_id,@login)
  15912.             if  @@error <> 0
  15913.                 return(1)
  15914.         end
  15915.     end
  15916.     else if @operation = 'drop'
  15917.     begin
  15918.         if @isntname is null and not exists (select * from MSpublication_access where
  15919.                 publication_id = @publication_id and
  15920.                 login = @login) 
  15921.         begin
  15922.             raiserror(15007,10,-1,@login)
  15923.             return 1
  15924.         end
  15925.         -- Do check existense when dropping since the login might be dropped
  15926.         -- outside replication already.
  15927.         delete MSpublication_access where
  15928.                 publication_id = @publication_id and
  15929.                 login = @login
  15930.         if  @@error <> 0
  15931.             return(1)
  15932.     end
  15933.     else if @operation = 'check'
  15934.     begin
  15935.         -- Cover the case when
  15936.         -- the NT user is not in syslogins
  15937.         if @isntname is null and suser_sid(@login) is not null
  15938.             select @isntname = 1
  15939.  
  15940.         -- If the login is valid NT login, call set user
  15941.         if @isntname = 1
  15942.         begin
  15943.             setuser @login
  15944.             if @@error <> 0
  15945.             begin
  15946.                 raiserror (21142, 16, -1, @@servername, @login)
  15947.                 return(1)
  15948.             end
  15949.         end
  15950.         if exists (select * from MSpublication_access l where
  15951.             publication_id = @publication_id and
  15952.             (l.login = @login or (@isntname = 1 and exists (select * from master..syslogins
  15953.                 where sid = suser_sid(l.login) and isntgroup = 1 and is_member(l.login) = 1))))
  15954.             set @has_access = 1
  15955.         else
  15956.             set @has_access = 0
  15957.         if @isntname = 1
  15958.         begin
  15959.             setuser
  15960.             if @@error <> 0
  15961.                 return(1)
  15962.         end        
  15963.     end
  15964.     else if @operation = 'help'
  15965.     begin
  15966.         select login from MSpublication_access where
  15967.                     publication_id = @publication_id and
  15968.                     login like @login
  15969.     end
  15970.     else if @operation = 'get_publications'
  15971.     begin
  15972.         -- Avoid setuser failure and cover the case of that 
  15973.         -- the NT user is not in syslogins
  15974.         if @isntname is null and suser_sid(@login) is not null
  15975.         begin
  15976.             exec @retcode = master.dbo.xp_logininfo
  15977.                 @login, N'all', @privilege output
  15978.             if @privilege is not null
  15979.                 select @isntname = 1
  15980.         end
  15981.  
  15982.         -- If the login is valid NT login, call set user
  15983.         if @isntname = 1
  15984.         begin
  15985.             setuser @login
  15986.             -- If the login is invalid, don't return any result.
  15987.             if @@error <> 0
  15988.             begin
  15989.                 raiserror (21142, 16, -1, @@servername, @login)
  15990.                 return(0)
  15991.             end
  15992.         end
  15993.         select p.publisher_db, p.publication from MSpublication_access l,
  15994.             MSpublications p where
  15995.             -- Get all the non default publications that have the login in the access list
  15996.             (
  15997.             -- If login match or there is an NT group in the access list and @login is integrated
  15998.             (l.login = @login or ( @isntname = 1 and exists (select * from master..syslogins
  15999.                 where sid = suser_sid(l.login) and isntgroup = 1 and is_member(l.login) = 1))) and
  16000.             l.publication_id = p.publication_id and
  16001.             p.publisher_id = @publisher_id
  16002.             ) 
  16003.         if @isntname = 1
  16004.         begin
  16005.             setuser
  16006.             if @@error <> 0
  16007.                 return(1)
  16008.         end        
  16009.     end
  16010.     else if @operation = 'get_logins'
  16011.     begin
  16012.         select loginname from master..syslogins where
  16013.             hasaccess = 1
  16014.     end
  16015. GO
  16016.  
  16017. raiserror(15339,-1,-1,'sp_MScheck_pull_access')
  16018. GO
  16019.  
  16020. CREATE PROCEDURE sp_MScheck_pull_access (
  16021.     @agent_id int = 0,
  16022.     @agent_type int = 0, -- 0 is tran; 1 is merge
  16023.     @publication_id int = 0
  16024.         ) AS
  16025.  
  16026.     declare @retcode int
  16027.  
  16028.     -- sysadmin or db_owner have access
  16029.     if is_srvrolemember('sysadmin') = 1 or 
  16030.         is_member('db_owner') = 1
  16031.         return 0
  16032.  
  16033.     -- Need login_time to uniquely identify a connection.
  16034.     declare @login_time datetime
  16035.     select @login_time = login_time from master..sysprocesses where spid = @@spid
  16036.  
  16037.     -- For merge change to use publication_id
  16038.     if @agent_id <> 0 and @agent_type = 1
  16039.     begin
  16040.         select @publication_id = p.publication_id from
  16041.                 MSmerge_agents a, MSpublications p where
  16042.                 a.id = @agent_id and
  16043.                 a.publisher_id = p.publisher_id and
  16044.                 a.publisher_db = p.publisher_db and
  16045.                 a.publication = p.publication
  16046.         select @agent_id = 0
  16047.     end
  16048.  
  16049.     -- In cache, return success
  16050.     if exists (select * from tempdb.dbo.MSdistributor_access where 
  16051.         spid = @@spid and
  16052.         login_time = @login_time and
  16053.         db_id = db_id() and
  16054.         (publication_id = @publication_id and
  16055.         agent_id = @agent_id and
  16056.         agent_type = @agent_type) or
  16057.         -- All 0s is used by sp_MSadd_repl_error, which just require the 
  16058.         -- login to be in cache regardless of the publication id and agent_id.
  16059.         -- This means that once a agent get into the distribution db, it
  16060.         -- can add any error.
  16061.         (@publication_id = 0 and @agent_id = 0 and @agent_type = 0))
  16062.         return (0)
  16063.  
  16064.     -- Cover sp_MSadd_repl_error case
  16065.     if @publication_id = 0 and @agent_id = 0 and @agent_type = 0
  16066.     begin
  16067.         RAISERROR (14126, 11, -1)
  16068.         return (1)
  16069.     end
  16070.  
  16071.     declare @isntname bit
  16072.     declare @offensive_pub_id int
  16073.  
  16074.     -- Check to see if the login is NT login
  16075.     select @isntname = isntname from master..syslogins where
  16076.         sid = suser_sid()
  16077.     -- If the login does not exists, check to see if the login is a NT login that
  16078.     -- has access to the server.
  16079.     if @isntname is null
  16080.     begin
  16081.         -- If it is an NT login
  16082.         if suser_sid() is not null
  16083.             select @isntname = 1
  16084.         -- If it is not an NT login
  16085.         else
  16086.             select @isntname = 0
  16087.     end
  16088.  
  16089.     -- Check security based on agent_id
  16090.     -- We know it is distribution agent. See above.
  16091.     if @agent_id <> 0 
  16092.     begin
  16093.         select top 1 @offensive_pub_id = s.publication_id from MSsubscriptions s where 
  16094.             s.agent_id = @agent_id and
  16095.             not exists (select * from MSpublication_access l where
  16096.                 l.publication_id = s.publication_id and
  16097.             -- Current login has no access
  16098.             (suser_sid(l.login) = suser_sid() or (@isntname = 1 and exists 
  16099.                 (select * from master..syslogins where 
  16100.                     sid = suser_sid(l.login) and isntgroup = 1 and is_member(l.login) = 1))))
  16101.         
  16102.         if @offensive_pub_id is not null
  16103.             goto NO_ACCESS
  16104.     end
  16105.     -- Check security based on publication_id
  16106.     else
  16107.     begin
  16108.         declare @publisher_id smallint
  16109.     
  16110.         if not exists (select * from MSpublication_access l where
  16111.             l.publication_id = @publication_id and
  16112.             (suser_sid(l.login) = suser_sid() or (@isntname = 1 and exists 
  16113.                 (select * from master..syslogins where 
  16114.                     sid = suser_sid(l.login) and isntgroup = 1 and is_member(l.login) = 1))))
  16115.         begin
  16116.             select @offensive_pub_id = @publication_id
  16117.             goto NO_ACCESS
  16118.         end
  16119.     end
  16120.  
  16121.     -- If we are here, we know that the connection has access and is not in the cache
  16122.     -- add it in to the cache.
  16123.         
  16124.     -- Clear the cache to keep it small.
  16125.     exec @retcode = dbo.sp_MSflush_access_cache
  16126.     if @retcode <> 0 or @@error <> 0
  16127.         return (1)
  16128.         
  16129.  
  16130.     insert tempdb.dbo.MSdistributor_access
  16131.         (spid, db_id, agent_id, agent_type, publication_id, login_time) values
  16132.         (@@spid, db_id(), @agent_id, @agent_type, @publication_id, @login_time)
  16133.  
  16134.     if @@error <> 0
  16135.         return (1)
  16136.  
  16137.     return (0)
  16138.  
  16139. NO_ACCESS:
  16140.  
  16141.     -- We don't have access if we reach here, return error
  16142.     declare @login sysname
  16143.     select @login = suser_sname(suser_sid())
  16144.     declare @publication sysname
  16145.     select @publication = publication from MSpublications where publication_id = @offensive_pub_id
  16146.     raiserror(21049, 16, -1, @login, @publication);
  16147.     return(1)
  16148.  
  16149. GO
  16150.  
  16151. raiserror(15339,-1,-1,'sp_MSdrop_6x_publication')
  16152. GO
  16153.  
  16154. -- This stored procedure is called by sp_droptask when 6.x publications are dropped.
  16155. create procedure sp_MSdrop_6x_publication
  16156. @job_id UNIQUEIDENTIFIER
  16157. as
  16158.     declare @publisher sysname
  16159.     declare @publisher_db sysname
  16160.     declare @publication sysname
  16161.     declare @retcode int
  16162.  
  16163.     -- Get publication information
  16164.     select @publisher = srvname, @publisher_db = publisher_db, @publication = publication from 
  16165.         MSsnapshot_agents, master..sysservers where
  16166.         job_id = @job_id and
  16167.         srvid = publisher_id
  16168.  
  16169.     -- Remove the publication and snapshot agent
  16170.     exec @retcode = dbo.sp_MSdrop_publication
  16171.         @publisher = @publisher,
  16172.         @publisher_db = @publisher_db,
  16173.         @publication = @publication 
  16174.     if @@ERROR <> 0 or @retcode <> 0
  16175.         return 1
  16176. GO
  16177.  
  16178. raiserror(15339,-1,-1,'sp_MShelp_distribution_agentid')
  16179. GO
  16180.  
  16181. CREATE PROCEDURE sp_MShelp_distribution_agentid
  16182. @publisher_id smallint,
  16183. @publisher_db sysname,
  16184. @publication sysname = NULL,
  16185. @subscriber_id smallint,
  16186. @subscriber_db sysname,
  16187. @subscription_type int, /* 0 = push 1 = pull 2=anonymous, */
  16188. -- For anonymous only
  16189. @subscriber_name    sysname = NULL,
  16190. @anonymous_subid    uniqueidentifier = NULL,
  16191. @reinitanon         bit = 0
  16192. as
  16193.  
  16194.     set nocount on
  16195.     declare @last_status int
  16196.     declare @expired int
  16197.     declare @independent_agent bit
  16198.     declare @xact_seqno_length int
  16199.     declare @agent_id int
  16200.     declare @third_party_flag bit
  16201.     declare @retcode int
  16202.     declare @anonymous int
  16203.     declare @sub_agent_id int
  16204.     declare @retention int
  16205.     declare @success int
  16206.     declare @last_sync datetime
  16207.     select @anonymous = 2
  16208.     select @success = 2
  16209.     select @expired = 0
  16210.  
  16211.     select  top 1
  16212.         @third_party_flag = thirdparty_flag,
  16213.         @independent_agent = independent_agent,
  16214.         @retention = retention
  16215.         from MSpublications where
  16216.         publisher_id = @publisher_id and
  16217.         publisher_db = @publisher_db and
  16218.         (publication = @publication or @publication is null)
  16219.  
  16220.     if @subscription_type = @anonymous
  16221.     begin
  16222.         exec @retcode = dbo.sp_MSadd_anonymous_agent
  16223.             @publisher_id   = @publisher_id,
  16224.             @publisher_db   = @publisher_db,
  16225.             @publication    = @publication,
  16226.             @subscriber_db  = @subscriber_db,
  16227.             @subscriber_name = @subscriber_name,
  16228.             @anonymous_subid =  @anonymous_subid output,
  16229.             @agent_id = @agent_id output,
  16230.             @reinitanon = @reinitanon
  16231.         if @@error <> 0 or @retcode <> 0
  16232.             return (1)
  16233.  
  16234.         select @sub_agent_id = anonymous_agent_id from
  16235.             MSdistribution_agents where
  16236.             id = @agent_id
  16237.     end 
  16238.     else
  16239.     begin
  16240.         select @agent_id = id
  16241.         from MSdistribution_agents where
  16242.              publisher_id = @publisher_id and
  16243.              publisher_db = @publisher_db and
  16244.              (publication = @publication or
  16245.              (@publication is null and publication = N'ALL')) and
  16246.              subscription_type = @subscription_type and
  16247.              subscriber_id = @subscriber_id and
  16248.              subscriber_db = @subscriber_db
  16249.  
  16250.         -- If cannont find the agent entry, ignore @subscriber_db and try again 
  16251.         -- for non SQL subscribers
  16252.         -- Note that this preserved backward compatibility for 7.0 publisher or 7.0 pull distribution agent.
  16253.         -- In 7.0, we hard code name 'DSN'.
  16254.         if @agent_id is null 
  16255.         begin
  16256.             declare @publisher sysname
  16257.             declare @subscriber sysname
  16258.             select @publisher = srvname from master..sysservers where
  16259.                 srvid = @publisher_id
  16260.             select @subscriber = srvname from master..sysservers where
  16261.                 srvid = @subscriber_id
  16262.             if exists (select * from MSsubscriber_info where
  16263.                 publisher = @publisher and
  16264.                 subscriber = @subscriber and
  16265.                 type <> 0)
  16266.             begin
  16267.                 select @agent_id = id
  16268.                 from MSdistribution_agents where
  16269.                      publisher_id = @publisher_id and
  16270.                      publisher_db = @publisher_db and
  16271.                      (publication = @publication or
  16272.                      (@publication is null and publication = N'ALL')) and
  16273.                      subscription_type = @subscription_type and
  16274.                      subscriber_id = @subscriber_id 
  16275.             end
  16276.         end
  16277.  
  16278.         select @sub_agent_id = @agent_id
  16279.     end
  16280.  
  16281.     -- Note: can not fail if publication not exists but agent exists
  16282.     -- It is an upgrade case. 
  16283.     if @third_party_flag is null and @agent_id is null
  16284.     begin
  16285.         -- The publication(s) does not exist
  16286.         RAISERROR (21073, 16, -1)
  16287.         return(1)
  16288.     end
  16289.  
  16290.     if @agent_id is null 
  16291.     begin
  16292.         -- If the specified publication name is in MSpublications table then
  16293.         -- the publication is configured to use a non-independent distribution
  16294.         -- agent. Raise a different error if this is the case
  16295.         if @independent_agent = 0 and lower(@publication) <> N'all' and
  16296.             @publication is not null and 
  16297.             exists (select * from MSdistribution_agents 
  16298.                     where publication = N'ALL' and 
  16299.                           publisher_id = @publisher_id and
  16300.                           publisher_db = @publisher_db and
  16301.                           subscription_type = @subscription_type and
  16302.                           subscriber_id = @subscriber_id and
  16303.                           subscriber_db = @subscriber_db)  
  16304.         begin
  16305.             RAISERROR (21133, 16, -1, @publication)
  16306.         end
  16307.         else
  16308.         begin
  16309.             -- Invalid subscription
  16310.             RAISERROR (21056, 16, -1, @publication)
  16311.         end
  16312.         return(1)
  16313.     end
  16314.  
  16315.     -- It is an upgrade case. 
  16316.     if @third_party_flag is null 
  16317.         select @third_party_flag = 0
  16318.  
  16319.     /*
  16320.     ** Get the time when the subscription is active and succeed.
  16321.     */
  16322.     select Top 1 @last_status=runstatus, @last_sync = time from MSdistribution_history 
  16323.         where agent_id = @agent_id order by timestamp DESC
  16324.     
  16325.     if @last_status = 6 and EXISTS (select * from MSdistribution_history where agent_id = @agent_id and runstatus = @success) 
  16326.                 select Top 1 @last_sync = time from MSdistribution_history where agent_id = @agent_id and runstatus = @success
  16327.                         order by timestamp DESC    
  16328.  
  16329.     if @last_sync is not NULL and @independent_agent = 1 --by pass the retention check for non-independent agnt
  16330.     begin
  16331.         if (@last_sync < dateadd(hour, -@retention, getdate())) 
  16332.            and (@retention <> 0)
  16333.                  select @expired = 1  
  16334.     end
  16335.  
  16336.     /* 
  16337.     ** Avoid returning a NULL value 
  16338.     ** Otherwise, distribution agent may fail
  16339.     */
  16340.     select @xact_seqno_length = 0
  16341.  
  16342.     /* 
  16343.     **  Get the lengh of xact_seqno
  16344.     **   Currently, unique across the publisher
  16345.     */
  16346.     select top 1 @xact_seqno_length = DATALENGTH(subscription_seqno)
  16347.     from MSsubscriptions s where
  16348.         agent_id = @sub_agent_id
  16349.  
  16350.     /* xact_seqno for snapshot trans are longer for native publishers*/
  16351.     if @third_party_flag = 0
  16352.     begin
  16353.         if @xact_seqno_length = 8 or @xact_seqno_length = 10
  16354.             select @xact_seqno_length = @xact_seqno_length + 4
  16355.     end
  16356.  
  16357.     -- Security check. Do it here to let the agent fail at the beginning
  16358.     exec @retcode = dbo.sp_MScheck_pull_access
  16359.         @agent_id = @sub_agent_id,
  16360.         @agent_type = 0 -- distribution agent
  16361.     if @@error <> 0 or @retcode <> 0
  16362.         return (1)
  16363.  
  16364.     select 
  16365.         'xact_seqno_length' = @xact_seqno_length,
  16366.         'agent_id' = @agent_id,
  16367.         'agent_name' = name,
  16368.         'anonymous subid' = anonymous_subid,
  16369.         'expired ' = @expired
  16370.         from MSdistribution_agents where id = @agent_id
  16371.  
  16372. GO
  16373.  
  16374. raiserror(15339,-1,-1,'sp_MSmarkreinit')
  16375. GO
  16376. CREATE PROCEDURE sp_MSmarkreinit
  16377. @publisher sysname,
  16378. @publisher_db sysname,
  16379. @publication sysname,
  16380. @subscriber sysname,       
  16381. @subscriber_db sysname,
  16382. @reset_reinit    int
  16383. AS
  16384.     set nocount on
  16385.  
  16386.     declare @publisher_id smallint
  16387.     declare @subscriber_id smallint
  16388.     declare @publication_id int
  16389.     declare @retcode int
  16390.     declare @reinited int
  16391.     declare @unreinited int
  16392.     declare @status int
  16393.  
  16394.     select @reinited = 4  -- status=4 means this subscription has been reinited
  16395.     select @unreinited = 1 -- status=1 means this subscription not reinited
  16396.  
  16397.     if @reset_reinit = 1
  16398.         select @status = @reinited
  16399.     else
  16400.         select @status = @unreinited
  16401.     
  16402. -- Check if publisher is a defined as a distribution publisher in the current database
  16403.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  16404.     if @retcode <> 0
  16405.     begin
  16406.         return(1)
  16407.     end
  16408.  
  16409.     -- Get the publication information 
  16410.     select @publication_id = publication_id
  16411.         from MSpublications where 
  16412.         publisher_id = @publisher_id and
  16413.         publisher_db = @publisher_db and
  16414.         publication = @publication
  16415.     if @publication_id is NULL
  16416.     begin
  16417.         raiserror (20026, 11, -1, @publication)
  16418.         return (1)
  16419.     end
  16420.  
  16421.     -- Get subscriber info
  16422.     select @subscriber_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  16423.  
  16424.     update MSmerge_subscriptions set status = @status where
  16425.         publisher_id = @publisher_id and 
  16426.         publisher_db = @publisher_db and 
  16427.         publication_id = @publication_id and
  16428.         subscriber_id = @subscriber_id and
  16429.         subscriber_db = @subscriber_db
  16430.     if @@error<>0 
  16431.         return (1)
  16432. GO        
  16433.  
  16434.  
  16435.  
  16436. raiserror(15339,-1,-1,'sp_MSreinit_subscription')
  16437. GO
  16438. CREATE PROCEDURE sp_MSreinit_subscription
  16439. @publisher_name sysname,
  16440. @publisher_db sysname,
  16441. @publication sysname = 'all',
  16442. @subscriber_name    sysname = 'all',
  16443. @subscriber_db sysname = 'all'
  16444. as
  16445.     set nocount on
  16446.     declare @proc nvarchar(2048)
  16447.     declare @retcode int
  16448.  
  16449.     if @publisher_name IS NULL or NOT EXISTS (select * from master..sysservers as ss, MSpublications as msp
  16450.         where lower(ss.srvname) = lower(@publisher_name) and msp.publisher_id = ss.srvid)
  16451.     begin
  16452.         return (1)
  16453.     end
  16454.  
  16455.     if @publisher_db IS NULL
  16456.         select @publisher_db = ''
  16457.  
  16458.     select @proc = @publisher_name + '.' + @publisher_db + '.dbo.sp_reinitsubscription '
  16459.     exec @retcode = @proc @publication, 'all', @subscriber_name, @subscriber_db
  16460.  
  16461.     return (@retcode)
  16462. go
  16463.  
  16464.    -- View for delivered and undelivered commands.   RHS  6-4-98
  16465.    -- Since the view is likely to change, just recreate it each time.
  16466.    IF EXISTS (SELECT * FROM sysobjects where name='MSdistribution_status' and type='V')
  16467.     DROP VIEW dbo.MSdistribution_status
  16468.  
  16469.     /****************************************************************************/
  16470.     raiserror('Creating view MSdistribution_status', 0,1)
  16471.         /****************************************************************************/    
  16472. go
  16473.  
  16474. CREATE VIEW MSdistribution_status (article_id,agent_id,UndelivCmdsInDistDB,DelivCmdsInDistDB)
  16475. as
  16476. -- Note that this view does not account for (i.e. exclude from counts) commands that do not need to be delivered 
  16477. -- because of loopback or syncronous updating subscribers, nor subscriptions never activated.
  16478. -- It also may not be exact due to use of NOLOCK - so that it does not cause blocking or deadlock issues.
  16479. SELECT t.article_id,s.agent_id,
  16480. 'UndelivCmdsInDistDB'=SUM(CASE WHEN xact_seqno > h.maxseq THEN 1 ELSE 0 END),
  16481. 'DelivCmdsInDistDB'=SUM(CASE WHEN xact_seqno <=  h.maxseq THEN 1 ELSE 0 END)
  16482. FROM    (SELECT    article_id,publisher_database_id, xact_seqno
  16483.     FROM MSrepl_commands (NOLOCK) ) as t
  16484. JOIN (SELECT agent_id,article_id,publisher_database_id FROM MSsubscriptions (NOLOCK) ) AS s 
  16485. ON (t.article_id = s.article_id AND t.publisher_database_id=s.publisher_database_id )
  16486. JOIN (SELECT agent_id,'maxseq'= isnull(max(xact_seqno),0x0) FROM MSdistribution_history (NOLOCK) GROUP BY agent_id) as h
  16487. ON (h.agent_id=s.agent_id)
  16488. GROUP BY t.article_id,s.agent_id
  16489. go
  16490.     
  16491. EXEC dbo.sp_MS_marksystemobject 'MSdistribution_status'
  16492. -- As this view can add considerable overhead when queried, it intentionally is not granted public access by default.
  16493. -- A site may so grant it if it wants to of course>
  16494. GRANT SELECT ON MSdistribution_status to dbo
  16495. go
  16496.  
  16497.  
  16498. raiserror(15339,-1,-1,'sp_browsereplcmds')
  16499. GO
  16500.  
  16501. create procedure sp_browsereplcmds 
  16502. @xact_seqno_start nchar(22) = NULL, 
  16503. @xact_seqno_end nchar(22) = NULL,
  16504. @originator_id int = NULL,
  16505. @publisher_database_id int = NULL,
  16506. @article_id int = NULL,
  16507. @command_id int = NULL
  16508. as
  16509. declare @query nvarchar( 4000 )
  16510. declare @dbname sysname
  16511.  
  16512. if( @command_id is not null )
  16513. begin
  16514.     if( @xact_seqno_start is null or @xact_seqno_end is null or @originator_id is null or @publisher_database_id is null or @article_id is null )
  16515.     begin
  16516.         raiserror( 21110, 16, -1 )
  16517.         return 1
  16518.     end
  16519.     else if @xact_seqno_start != @xact_seqno_end 
  16520.     begin
  16521.         raiserror( 21109, 16, -1 )
  16522.         return 1
  16523.     end
  16524. end
  16525.  
  16526. if @xact_seqno_start is null
  16527. begin
  16528.     select @xact_seqno_start = N'0x00000000000000000000'
  16529. end
  16530. if @xact_seqno_end is null
  16531. begin
  16532.     select @xact_seqno_end = N'0xFFFFFFFFFFFFFFFFFFFF'
  16533. end
  16534.  
  16535. select @query = N'select xact_seqno, convert( int, originator_id ), convert( int, publisher_database_id ), convert(int, article_id), convert( int, type ) & 32767, convert( int, partial_command ), command from MSrepl_commands '
  16536.  
  16537. if @command_id is not null
  16538. begin
  16539.     select @query = @query + N'where xact_seqno = ' + @xact_seqno_start  
  16540. end
  16541. else
  16542. begin
  16543.     select @query = @query + N'where xact_seqno >= ' + @xact_seqno_start + N' and xact_seqno <= ' + @xact_seqno_end 
  16544. end
  16545.  
  16546. if @originator_id is not null
  16547. begin
  16548.     select @query = @query + N' and originator_id = ' + convert( nvarchar, @originator_id )
  16549. end
  16550.  
  16551. if @publisher_database_id is not null
  16552. begin
  16553.     select @query = @query + N' and publisher_database_id = ' + convert( nvarchar, @publisher_database_id )
  16554. end
  16555.  
  16556. if @article_id is not null
  16557. begin
  16558.     select @query = @query + N' and article_id = ' + convert( nvarchar, @article_id )
  16559. end
  16560.  
  16561. if @command_id is not null
  16562. begin
  16563.     select @query = @query + N' and command_id >= ' + convert( nvarchar, @command_id )
  16564.     select @query = @query + N' and command_id <= ( select min( command_id ) from MSrepl_commands '
  16565.     select @query = @query + N' where xact_seqno = ' + @xact_seqno_start  
  16566.     select @query = @query + N' and originator_id = ' + convert( nvarchar, @originator_id )
  16567.     select @query = @query + N' and publisher_database_id = ' + convert( nvarchar, @publisher_database_id )
  16568.     select @query = @query + N' and article_id = ' + convert( nvarchar, @article_id ) 
  16569.     select @query = @query + N' and command_id >= ' + convert( nvarchar, @command_id )
  16570.     select @query = @query + N' and partial_command = 0 )'  
  16571. end
  16572.  
  16573. select @query = @query + N' order by originator_id, publisher_database_id, xact_seqno, article_id, command_id asc'
  16574.  
  16575. select @dbname = db_name()
  16576.  
  16577. exec master..xp_printstatements @query, @dbname
  16578. go
  16579.  
  16580.  
  16581.  
  16582. raiserror(15339,-1,-1,'sp_dumpparamcmd')
  16583. GO
  16584.  
  16585. create procedure sp_dumpparamcmd
  16586. @originator_id int,
  16587. @publisher_database_id int,
  16588. @article_id int,
  16589. @xact_seqno nchar(22)
  16590. as
  16591. declare @query nvarchar(2048)
  16592. declare @dbname sysname
  16593.  
  16594. select @query = N'select convert(int, partial_command) , command from MSrepl_commands '
  16595. select @query = @query + 'where type = 30 and xact_seqno = ' + @xact_seqno
  16596. select @query = @query + N' and originator_id = ' + convert( nvarchar, @originator_id )
  16597. select @query = @query + N' and publisher_database_id = ' + convert( nvarchar, @publisher_database_id )
  16598. select @query = @query + N' and article_id = ' + convert( nvarchar, @article_id )
  16599. select @query = @query + N' order by command_id asc'
  16600. select @dbname = db_name()
  16601.  
  16602. exec master..xp_displayparamstmt @query, @dbname, 1
  16603. go
  16604.  
  16605.  
  16606. /****************************************************************************/
  16607. print ''
  16608. print 'Adding user ''guest''.'
  16609. print ''
  16610. /****************************************************************************/
  16611. if not exists (select * from sysusers where
  16612.     name = N'guest' and
  16613.     hasdbaccess = 1)
  16614.     EXEC  dbo.sp_adduser 'guest'
  16615.  
  16616.  
  16617. grant execute on dbo.sp_MSdistribution_counters to public
  16618. GO 
  16619. grant execute on dbo.sp_MShelp_profile to public
  16620. GO
  16621.  
  16622. /* 
  16623. Stored procedures called by dist publisher.
  16624. distributor_admin will be added to db_owner role. Members of
  16625. db_owner have permission on all the stored procedures. 
  16626.  
  16627. -- Stored procedure used by remote publisher RPC
  16628. grant execute on dbo.sp_MSadd_publication to db_owner
  16629. grant execute on dbo.sp_MSchange_publication to db_owner
  16630. grant execute on dbo.sp_MSdrop_publication to db_owner
  16631. grant execute on dbo.sp_MSadd_article to db_owner
  16632. grant execute on dbo.sp_MSchange_article to db_owner
  16633. grant execute on dbo.sp_MSdrop_article to db_owner
  16634. grant execute on dbo.sp_MSadd_subscriber_info to db_owner
  16635. grant execute on dbo.sp_MSupdate_subscriber_info to db_owner
  16636. grant execute on dbo.sp_MSadd_subscriber_schedule to db_owner
  16637. grant execute on dbo.sp_MSupdate_subscriber_schedule to db_owner
  16638. grant execute on dbo.sp_MShelp_subscriber_info to db_owner
  16639. grant execute on dbo.sp_MSdrop_subscriber_info to db_owner
  16640. grant execute on dbo.sp_MSadd_snapshot_agent to db_owner
  16641. grant execute on dbo.sp_MSdrop_snapshot_agent to db_owner
  16642. grant execute on dbo.sp_MSadd_logreader_agent to db_owner
  16643. grant execute on dbo.sp_MSdrop_logreader_agent to db_owner
  16644. grant execute on dbo.sp_MSreset_subscription to db_owner
  16645.  
  16646. -- Stored procedure used by snapshot and logreader agents
  16647. grant execute on dbo.sp_MSadd_repl_command to db_owner
  16648. grant execute on dbo.sp_MSadd_repl_commands10 to db_owner
  16649. grant execute on dbo.sp_MSadd_repl_commands27 to db_owner
  16650. grant execute on dbo.sp_MSadd_repl_commands27hp to db_owner
  16651. grant execute on dbo.sp_MSadd_repl_commands27hp6x to db_owner
  16652. grant execute on dbo.sp_MSget_last_transaction to db_owner
  16653. grant execute on dbo.sp_MSset_snapshot_xact_seqno to db_owner
  16654. grant execute on dbo.sp_MSadd_snapshot_history to db_owner
  16655. grant execute on dbo.sp_MSadd_logreader_history to db_owner
  16656. grant execute on dbo.sp_MSdist_activate_auto_sub to db_owner
  16657. grant execute on dbo.sp_MSlock_auto_sub to db_owner
  16658. grant execute on dbo.sp_MSget_new_xact_seqno to db_owner
  16659. grant execute on dbo.sp_MSactivate_subscriptions to db_owner
  16660. grant execute on dbo.sp_MShelp_snapshot_agentid to db_owner
  16661. grant execute on dbo.sp_MShelp_logreader_agentid to db_owner
  16662. grant execute on dbo.sp_MSadd_subscription to public
  16663. grant execute on dbo.sp_MSupdate_subscription to public
  16664. grant execute on dbo.sp_MSdrop_subscription to public
  16665. grant execute on dbo.sp_MSadd_merge_subscription to public
  16666. grant execute on dbo.sp_MSdrop_merge_subscription to public
  16667.  
  16668. */
  16669.  
  16670.  
  16671.  
  16672. -- Stored procedures used by dist and merge agents. They are granted to public
  16673.  
  16674. grant execute on dbo.sp_MSmarkreinit to public
  16675. go
  16676.  
  16677. -- Procedures to retrieve actual data. Need security check inside
  16678. grant execute on dbo.sp_MSget_repl_commands to public
  16679. GO
  16680. grant execute on dbo.sp_MSget_repl_cmds_anonymous to public
  16681. GO
  16682.  
  16683. -- Procedures to modify meta data. Need security check inside.
  16684. grant execute on dbo.sp_MSadd_distribution_history to public
  16685. GO
  16686. grant execute on dbo.sp_MSadd_repl_error to public
  16687. GO
  16688. grant execute on dbo.sp_MSadd_repl_alert to public
  16689. GO
  16690. grant execute on dbo.sp_MSadd_replmergealert to public
  16691. GO
  16692. grant execute on dbo.sp_MSadd_merge_history to public
  16693. GO
  16694. grant execute on dbo.sp_MSadd_anonymous_agent to public
  16695. GO
  16696. grant execute on dbo.sp_MSadd_merge_anonymous_agent to public
  16697. GO
  16698.  
  16699. -- Procedures to retrieve meta data. No security check inside.
  16700. grant execute on dbo.sp_MSget_subscription_guid to public
  16701. GO
  16702. grant execute on dbo.sp_MSanonymous_status to public
  16703. GO
  16704. grant execute on dbo.sp_MSsubscription_status to public
  16705. GO
  16706. grant execute on dbo.sp_MShelp_merge_agentid to public
  16707. GO
  16708. grant execute on dbo.sp_MScheckretention to public
  16709. GO
  16710. grant execute on dbo.sp_MShelp_distribution_agentid to public
  16711. GO
  16712.  
  16713.  
  16714. declare @dbname sysname
  16715. select  @dbname = db_name()
  16716. execute('dump transaction ' +@dbname+ ' with no_log')
  16717. go
  16718. checkpoint
  16719.  
  16720. go
  16721.  
  16722. exec dbo.sp_MS_upd_sysobj_category 2  --Now do catalog updates.
  16723.  
  16724. go
  16725.  
  16726. EXEC dbo.sp_configure 'allow updates', 0
  16727. GO
  16728.  
  16729. reconfigure with override
  16730. GO
  16731. -- - ----
  16732.